2012-08-13 85 views
3

我想使用iCloud来存储我的应用程序的userSetting,这里是我的保存&加载代码:,它通常做的很好,但有时会崩溃的消息,如:尝试打开或恢复文档已经在飞行发送到dealloc实例所以我添加fileState日志befere openWithCompletionHandler它始终显示状态= UIDocumentStateClosed无论将崩溃或不,我保存数据时applecationDidEnterBackground和加载时,applicationDidBecomeActive。iCloud保存数据随着UIDocument崩溃

节省:

-(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提到的,如果您的应用程序试图调用[文件openWithCompletionHandler]时出现错误。

因为openWithCompletionHandler:异步打开文档,当再次调用该方法时文档可能仍然打开。

如果发生这种情况,您的应用程序最终会尝试打开文档两次(因为文档状态将保持UIDocumentStateClosed直到完成),这会导致异常被抛出。

+0

我已经解决了通过改变我的代码这个问题,但是当我写 [loadDocument saveToURL:documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:无] 在applicationDidEnterBackground,我的文件无法同步,有时到iCloud – 2012-09-14 05:24:28