我正在关注此问题(How To Save Data For Bookmarks?)的答案,以将书签保存到NSUserDefaults
。它非常简单,并且它第一次正常工作(当plist中没有条目时)。但之后它会尝试将之前保存的书签复制到新的NSMutableArray
应用程序崩溃中:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSMutableArray initWithCapacity:]:
method only defined for abstract class. Define -[__NSArrayM initWithCapacity:]!'
这是我的代码(稍加修改):
-(void) addStationToFavorites{
// Get the user defaults object
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *userSelectedService = [userDefaults objectForKey:@"idBikeServiceProvider"];
// Load your bookmarks (editable array)
NSMutableArray *bookmarks = [[NSMutableArray alloc] initWithCapacity:100];
NSArray *bookmarksLoaded = [userDefaults arrayForKey:[NSString stringWithFormat: @"favStationForService%@",userSelectedService]];
if (bookmarksLoaded != nil) {
[bookmarks initWithArray:bookmarksLoaded];
} else {
[bookmarks init];
}
// Add a bookmark
NSMutableDictionary *bookmark = [NSMutableDictionary new];
[bookmark setValue:pass_stationName forKey:pass_stationId];
[bookmarks addObject:bookmark];
// Save your (updated) bookmarks
[userDefaults setObject:bookmarks forKey:[NSString stringWithFormat: @"favStationForService%@",userSelectedService]];
[userDefaults synchronize];
// Memory cleanup
[bookmarks release];
//Show feedback
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@""
message:@"Added!"
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
答案 0 :(得分:3)
这是不正确的:
// Load your bookmarks (editable array)
NSMutableArray *bookmarks = [[NSMutableArray alloc]initWithCapacity:100]; // OK
NSArray *bookmarksLoaded = [userDefaults arrayForKey:[NSString stringWithFormat: @"favStationForService%@",userSelectedService]];
if (bookmarksLoaded != nil) {
[bookmarks initWithArray:bookmarksLoaded]; // NOT AGAIN
} else {
[bookmarks init]; // NOT AGAIN
}
不要在对象上多次调用init
方法。我怀疑这是你的错误的来源,因为NSArray / NSMutableArray被实现为"类集群"并且initWithCapacity:
返回的确切类不是NSMutableArray
,而是一些私有子类,它抱怨第二次初始化。这是实现相同目标的更好方法:
// Load your bookmarks (editable array)
NSMutableArray *bookmarks;
NSArray *bookmarksLoaded = [userDefaults arrayForKey:[NSString stringWithFormat: @"favStationForService%@",userSelectedService]];
if (bookmarksLoaded != nil) {
bookmarks = [bookmarksLoaded mutableCopy];
} else {
bookmarks = [[NSMutableArray alloc] initWithCapacity:100];
}
当您需要不可变容器对象的可变版本时,mutableCopy
方法非常有用。请注意,因为" copy"在方法名称中,您拥有结果并且必须稍后释放(除非您使用ARC或垃圾收集并且不需要担心它)。
答案 1 :(得分:2)
从NSUserDefaults返回的内容总是不可变的,无论它们在存储之前是否可变。
initWithCapacity:
仅在NSMutableArray上定义,而不在NSArray上定义。
编辑: 您似乎也在初始化对象两次:
// Load your bookmarks (editable array)
NSMutableArray *bookmarks = [[NSMutableArray alloc]initWithCapacity:100];
NSArray *bookmarksLoaded = [userDefaults arrayForKey:[NSString stringWithFormat: @"favStationForService%@",userSelectedService]];
if (bookmarksLoaded != nil) {
[bookmarks initWithArray:bookmarksLoaded];