Objective c 使用NSUserDefaults保存数组
我按照这个问题的答案将书签保存到NSUserDefaults中。它非常简单,并且在plist中没有条目时第一次正常工作。但随后它尝试将以前保存的书签复制到新的NSMutableArray中,应用程序崩溃:Objective c 使用NSUserDefaults保存数组,objective-c,arrays,plist,nsuserdefaults,Objective C,Arrays,Plist,Nsuserdefaults,我按照这个问题的答案将书签保存到NSUserDefaults中。它非常简单,并且在plist中没有条目时第一次正常工作。但随后它尝试将以前保存的书签复制到新的NSMutableArray中,应用程序崩溃: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray initWithCapacity:]: method only define
*** 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];
}
从NSUserDefaults返回的内容总是不可变的,不管它们在存储之前是否是可变的 初始容量: 仅在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];
从NSUserDefaults返回的内容总是不可变的,不管它们在存储之前是否是可变的 初始容量: 仅在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];
这是不正确的:
// 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或垃圾收集,并且不需要担心它。这是不正确的:
// 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或垃圾收集,并且不需要担心它。Ok,我将行更改为:NSMutableArray*bookmarks=[[NSMutableArray alloc]init];但仍然有相同的错误:/编辑了我的答案。您还初始化了两次对象。好的,我将行更改为:NSMutableArray*bookmarks=[[NSMutableArray alloc]init];但仍然有相同的错误:/编辑了我的答案。您还将初始化对象两次。