2012-10-29 100 views
0

我有一個類實現NSCoding協議的通知。
我有notifications.I數組我試圖保存NSUserDefaults.In我的應用程序委託通知的通知是一個NSMutableArray中包含objects.That是我的應用程序的委託通知:NSUserDefaults無法保存和讀取我的自定義對象

+ (void) initialize 
{ 
    NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults]; 
    [defaults registerDefaults: [NSDictionary dictionaryWithObject: [NSKeyedArchiver archivedDataWithRootObject: [NSArray array]] forKey: @"notificationsData"]]; 
} 


- (id) init 
{ 
    self=[super init]; 
    if(self) 
    { 
     NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults]; 
     NSData* notificationsData=[defaults objectForKey: @"notificationsData"]; 
     notifications= [[NSKeyedUnarchiver unarchiveObjectWithData: notificationsData]mutableCopy]; 
    } 
    return self; 
} 

- (void) applicationWillTerminate:(NSNotification *)notification 
{ 
    NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults]; 
    NSData* notificationsData=[NSKeyedArchiver archivedDataWithRootObject: notifications]; 
    [defaults setObject: notificationsData forKey: @"notificationsData"]; 
} 

在通知類文本和標題類型的NSString(包括讀寫),以及日期類型的NSDate(也這有讀寫屬性)。這是我如何實現NSCoding協議:

- (void) encodeWithCoder:(NSCoder *)aCoder 
{ 
    [aCoder encodeObject: date forKey: @"date"]; 
    [aCoder encodeObject: title forKey: @"title"]; 
    [aCoder encodeObject: text forKey: @"text"]; 
} 

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    self=[super init]; 
    if(self) 
    { 
     date=[aDecoder decodeObjectForKey: @"data"]; 
     title=[aDecoder decodeObjectForKey: @"title"]; 
     text=[aDecoder decodeObjectForKey: @"text"]; 
    } 
    return self; 
} 

所以我有這些問題:

  1. 當應用程序終止時,我在 通知類中獲得EXC_BAD_ACCESS,當我嘗試使用NSKeyedArchiver對文本進行編碼時;
  2. 當應用程序啓動時,通知未保存且數組總是長零 。

更新:隨着越來越多的調試,我發現,其中應用程序crashes.There是更多的代碼,看看(我使用表格視圖來顯示數據):

- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView 
{ 
    return [notifications count]; 
} 

- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{ 
    // Debug 
    id obj=[[notifications objectAtIndex: row] valueForKey: [tableColumn identifier]]; 
    Class class=[obj class]; 
    // What you see above is just for debug purposes 
    return [[notifications objectAtIndex: row] valueForKey: [tableColumn identifier]]; 
} 

- (void) tableViewSelectionDidChange:(NSNotification *)notification 
{ 
    NSInteger row=[tableView selectedRow]; 
    if(row >= 0 && row< [notifications count]) 
     [removeButton setEnabled: YES]; 
    else 
     [removeButton setEnabled: NO]; 
} 

被叫最後一個方法是這樣的:

- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; 

也許問題在於數據由於某種原因損壞,此方法返回不valid.Anyway應用中這種方法不崩潰的價值,但這種方法之後。
如果我從用戶默認加載兩個對象,只有一個對象在崩潰之前被加載(所以方法被調用一次)。
但是我仍然無法得到崩潰的真正原因。

更多代碼:

- (IBAction) addNotification :(id)sender 
{ 
    Notification* notification=[[Notification alloc]init]; 
    [notification setDate: [datePicker dateValue]]; 
    [notification setText: [textView string]]; 
    [notifications addObject: notification]; 
    [tableView reloadData]; 
} 

- (IBAction)removeNotification:(id)sender 
{ 
    [notifications removeObjectAtIndex: [tableView selectedRow]]; 
    [tableView reloadData]; 
} 

addNotification和removeNotification都是通過按鍵觸發。

編輯:我發現我沒有使用ARC,但即使我把它打開了應用程序崩潰。

回答

1

您可能需要調用[同步NSUserDefaults的],因爲當應用程序突然退出時不會自動發生:

- (void) applicationWillTerminate:(NSNotification *)notification 
{ 
    NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults]; 
    NSData* notificationsData=[NSKeyedArchiver archivedDataWithRootObject: notifications]; 
    [defaults setObject: notificationsData forKey: @"notificationsData"]; 
    [defaults synchronize]; 
} 
+0

是的,但它無論如何崩潰,仍然存在問題。 –

+1

如果用NSData * notificationsData = [NSKeyedArchiver archivedDataWithRootObject:@ []];''替換'NSData * notificationsData = [NSKeyedArchiver archivedDataWithRootObject:notifications];'會發生什麼? –

+0

這種情況下,應用程序運行平穩,沒有任何異常拋出。但當然,因爲數組是空的,我不能恢復以前執行的通知。我懷疑我如何實現協議有什麼問題。 –

2

在行:

date=[aDecoder decodeObjectForKey: @"data"]; 

@"data"不匹配的編碼器鍵。你真的想:

date=[aDecoder decodeObjectForKey: @"date"]; 
+0

謝謝,現在我取代了它,但程序仍然崩潰。 –

+0

你完全刪除了應用程序嗎?舊用戶的默認設置可能仍然存在。 – thelaws

+0

我使用NSUserDefault的resetStandardUserDefaults方法,但該應用程序仍然崩潰。 –

0

你猜不出是什麼病:是我不好,我忘了讓ARC和一些物品被釋放時,他們不應該。

相關問題