NSUserDefaults setObject 第一次没有保存

Posted

技术标签:

【中文标题】NSUserDefaults setObject 第一次没有保存【英文标题】:NSUserDefaults setObject not saving for first time 【发布时间】:2016-06-08 18:39:02 【问题描述】:

我的应用程序将 NSData(包含书签文件引用)列表保存到 NSUserDefaults,在应用程序过程的任何时候都以某种方式:

NSMutableArray *bookmarkedURLs = [[NSMutableArray alloc] init];
[bookmarkedURLs addObject:bookmark]; // 'bookmark' is a NSData object 
[[NSUserDefaults standardUserDefaults] setObject:bookmarkedURLs forKey:@"AppBookmarks"];
[[NSUserDefaults standardUserDefaults] synchronize];

当应用程序启动时,我检查了 NSUserDefaults 以填充保存的 NSData 列表:

bookmarkedURLs = [[[NSUserDefaults standardUserDefaults] objectForKey:@"AppBookmarks"] mutableCopy];
if (bookmarkedURLs.count == 0)

    bookmarkedURLs = [[NSMutableArray alloc] init];
    NSLog(@"INITIALIZED");

else

    NSLog(@"STORES NSDATA LIST");
    ....

我遇到的问题可以按以下步骤解决:

    “AppBookmarks”键没有保存 NSUserDefaults 数据 通过“AppBookmarks”键将 NSData 保存到 NSUserDefaults 重新启动应用程序 应用程序尝试从 NSUserDefaults 的“AppBookmarks”键填充 NSMutableArray,但始终找到 0 条记录 我再次将新的 NSData 保存到“AppBookmarks”键 重新启动应用程序 应用程序尝试从“AppBookmarks”填充 NSMutableArray,这一次它找到了保存的记录。 此后任何重新启动应用程序或添加到“AppBookmarks”的新 NSData 都不会失败

因此,只要没有保存数据到 NSUserDefaults 并且我保存了一个值,它就不会第一次加载或保存。此后,任何保存和加载的尝试都可以正常工作。

【问题讨论】:

您确定书签是 NSURL 对象吗?据我所知,NSUserDefault 仅适用于包含 NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary 的数组。 谢谢指点。我纠正了我的问题。 尝试更改 bookmarkedURLs = [[[NSUserDefaults standardUserDefaults] objectForKey:@"AppBookmarks"] mutableCopy]; with: bookmarkedURLs = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"AppBookmarks"]]; 我不认为这是我们如何加载的问题 - 因为在 first 尝试失败后现有进程可以正常工作。从第二次开始保存和加载效果很好。 【参考方案1】:

试试这个:

NSMutableArray *bookmarkedURLs = [[NSMutableArray alloc] init];
[bookmarkedURLs addObject:bookmark]; // 'bookmark' is a NSURL object 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:bookmarkedURLs forKey:@"AppBookmarks"];
[defaults synchronize];

希望对你有帮助。

【讨论】:

谢谢;但是将 NSUserDefaults 存储到字段并使用也没有帮助。 您问我如何生成bookmark 对象?这是一个NSURLBookmarkCreationWithSecurityScope NSData 对象 - 所以我在用户选择任何文件/文件夹时在NSOpenPanel 事件之后创建它,我将选定的文件路径添加到 URL 书签并获取 NSData (bookmark) 对象。【参考方案2】:

你可以这样做,

     NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];

// for example
NSURL *url1;  // your url1
NSURL *url2;   // your url2

//Set data to userdefaults

NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:url1,url2, nil]; // Store urls directly in array

NSData *bookMarkdata = [NSKeyedArchiver archivedDataWithRootObject:arr]; // convert whole array in data

[myDefaults setObject:bookMarkdata forKey:@"AppBookmarks"];  // save that data object to userdefaults
[myDefaults synchronize];

//Retreive data from userdefaults

NSData *resultData = [myDefaults objectForKey:@"AppBookmarks"];  //retrieve data from user defaults

NSMutableArray *resultArr = [NSKeyedUnarchiver unarchiveObjectWithData:resultData]; // get result array from data

【讨论】:

[NSKeyedUnarchiver unarchiveObjectWithData:resultData] 总是返回 null NSMutableArray,即使是 [[NSKeyedUnarchiver unarchiveObjectWithData:resultData] mutableCopy]。我可以确认在调用 [NSKeyedArchiver archivedDataWithRootObject: bookmarkedURLs] 时,可变数组中有超过 0 个项目。

以上是关于NSUserDefaults setObject 第一次没有保存的主要内容,如果未能解决你的问题,请参考以下文章

NSUserDefaults setObject:forKey 死锁?

NSUserDefaults setObject 方法导致应用在 ios8 中崩溃

NSUserDefaults存取失败

NSUserDefaults的使用

同步 NSUserDefaults 没有效果

使用常量 NSString 作为 NSUserDefaults 的键