我有一个实现 NSCoding 协议的类 Notification。
我有一个通知数组。我正在尝试使用 NSUserDefaults 保存通知。在我的应用程序委托通知中是一个包含通知对象的 NSMutableArray。这是我的应用程序委托:
+ (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"];
}
在 Notification 类中,文本和标题是 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;
}
所以我有这些问题:
- 当应用程序终止时,当我尝试使用 NSKeyedArchiver 对文本进行编码时,我在 Notification 类中得到 EXC_BAD_ACCESS;
- 通知不会被保存,并且当应用程序启动时数组总是长零。
更新:通过更多调试,我发现了应用程序崩溃的位置。还有更多代码可以查看(我正在使用表格视图来显示数据):
- (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;
可能问题是数据以某种方式损坏并且此方法返回的值无效。无论如何应用程序不会在此方法中崩溃,而是在此方法之后。
如果我从用户默认值加载两个对象,则在崩溃之前只加载一个对象(因此该方法被调用一次)。
但是我仍然无法获得崩溃的真正原因。
更多代码:
- (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,但即使我打开它,应用程序也会崩溃。