iCloud保存数据与UIDocument崩溃
Posted
技术标签:
【中文标题】iCloud保存数据与UIDocument崩溃【英文标题】:iCloud Save data With UIDocument crash 【发布时间】:2012-08-13 01:31:03 【问题描述】:我正在尝试使用 iCloud 来存储我的应用程序的 userSetting,这是我的 Save & Load Code: ,它通常运行良好,但有时会崩溃并显示如下消息:尝试打开或恢复已经打开的文档或在飞行中恢复操作或发送到dealloc实例所以我在openWithCompletionHandler之前添加fileState日志它总是显示状态= UIDocumentStateClosed无论是否会崩溃,我在applecationDidEnterBackground时保存数据并在applicationDidBecomeActive时加载.
保存:
-(void)storeToiCloud
NSURL *baseURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (baseURL)
NSURL *documentsURL = [baseURL URLByAppendingPathComponent:@"Documents"];
NSURL *documentURL = [documentsURL URLByAppendingPathComponent:[NSString stringWithFormat:@"userSetting"]];
if (!loadDocument)
self.loadDocument = [[MyUserDefaultsDocument alloc] initWithFileURL:documentURL];
loadDocument.myUserDefault = [MyUserDefaults standardUserDefaults];
[loadDocument saveToURL:documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success)
];
加载:
-(BOOL)shouldSynciCloud
if (![Utility iCloudEnable])
return NO;
NSURL *baseURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (baseURL)
self.query = [[[NSMetadataQuery alloc] init] autorelease];
[self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == 'userSetting'", NSMetadataItemFSNameKey];
[self.query setPredicate:predicate];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(queryDidFinish:) name:NSMetadataQueryDidFinishGatheringNotification object:self.query];
[self.query startQuery];
[Utility showSpinner];
return YES;
return NO;
- (void)queryDidFinish:(NSNotification *)notification
NSMetadataQuery *query = [notification object];
// Stop Updates
[query disableUpdates];
// Stop Query
[query stopQuery];
[query.results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
NSURL *documentURL = [(NSMetadataItem *)obj valueForAttribute:NSMetadataItemURLKey];
if([[documentURL lastPathComponent] hasPrefix:@"userSetting"])
self.document = [[MyUserDefaultsDocument alloc] initWithFileURL:documentURL];
NSString* message;
if (document.documentState == UIDocumentStateNormal)
message = @"UIDocumentStateNormal";
else if (document.documentState == UIDocumentStateClosed)
message = @"UIDocumentStateClosed";
else if(document.documentState == UIDocumentStateEditingDisabled)
message = @"UIDocumentStateEditingDisabled";
else if(document.documentState == UIDocumentStateInConflict)
message = @"UIDocumentStateInConflict";
else if(document.documentState == UIDocumentStateSavingError)
message = @"UIDocumentStateSavingError";
NSLog(@"state = %@",message);
[document openWithCompletionHandler:^(BOOL success)
if (success)
MyUserDefaults *prefs = [MyUserDefaults standardUserDefaults];
NSData *book =[document.myUserDefault.realDict objectForKey:@"realbook"];
NSData *readSetting = [document.myUserDefault.realDict objectForKey:@"epubRS"];
if (book&&[[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudBook"])
[prefs setObject:book forKey:@"realbook"];
[Utility reloadRealBooks];
if (readSetting&&[[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudSetting"])
[prefs setObject:readSetting forKey:@"epubRS"];
[Utility setEpubReadSettingFromData:readSetting];
[prefs save];
[[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSynced" object:nil];
[Utility removeSpinner];
else
[[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSyncfailed" object:nil];
[Utility removeSpinner];
];
];
if ([query.results count]==0)
[[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSyncfailed" object:nil];
[Utility removeSpinner];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
【问题讨论】:
【参考方案1】:如this question 中所述,如果您的应用尝试连续两次调用 [document openWithCompletionHandler:] 方法,则会发生错误。
由于openWithCompletionHandler: 异步打开文档,再次调用该方法时,文档可能还在打开中。
如果发生这种情况,您的应用最终会尝试打开文档两次(因为文档状态将保持 UIDocumentStateClosed 直到完成),这会导致引发异常。
【讨论】:
我已经通过更改我的代码解决了这个问题,但是当我在 applicationDidEnterBackground 写 [loadDocument saveToURL:documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:nil] 时,我的文件有时无法同步到 iCloud以上是关于iCloud保存数据与UIDocument崩溃的主要内容,如果未能解决你的问题,请参考以下文章