2012-06-11 18 views
2

我有一個使用iCloud同步的項目,但它無法正常工作。首先,我得到一組更改的對象,然後將它們轉換爲CSV字符串(這將成爲雲中UIDocuments的內容),然後將它們上傳到iCLoud。如果我的對象少於400個,則一切正常,但是如果我有更多 - 應用程序掛起。用於iCloud的大量UID文檔

我試過使用本地autorelease池,我已經把大數組拆分成小數組。但它沒有幫助。

上傳大量UID文件到iCloud的最佳方式是什麼? 我上傳方法:

- (void)pushChangesToCloud:(NSArray *)changedObjects { 

    for (ObjectClass *someObject in changedObjects) { 
     NSURL *pathToSyncDoc = [[self urlForDocumentsFolderIniCloud] URLByAppendingPathComponent:someObject.name]; 

     CustomUIDocument *syncDoc = [[[CustomUIDocument alloc] initWithFileURL:pathToSyncDoc] autorelease]; 
     // converting object to CSV string 
     NSString *csvContents = [SomeClass convertObjectToCSV:someObject];  
     syncDoc.documentContent = csvContents; 

     [syncDoc saveToURL:[syncDoc fileURL] 
      forSaveOperation:UIDocumentSaveForCreating 
     completionHandler:^(BOOL success) { 
      if (success) { 
       NSLog(@"YAY!"); 
      } else { 
       NSLog(@" D: "); 
      } 
     }]; 
    } 
} 

在此先感謝和抱歉,我的英語水平。

+0

你試過用'retain' /'release'手動內存管理呢? – Eimantas

+0

@Eimantas,謝謝你的回答。是的,最初是這樣做的。但在數據量很大的錯誤後,我決定應該使用autorelease和本地自動釋放池來實現。 –

+0

我能想到的另一個原因是用於後臺處理(即保存)的隊列可以用所有對象這可能會導致崩潰。您可以嘗試使用自己的串行隊列重新實現保存代碼。 – Eimantas

回答

1

我終於明白我的問題了,感謝@Eimantas的幫助。他對於超載隊列是正確的。由於「saveToUrl:forSaveOperation:completionHandler:」是I/O操作,因此隊列創建了大量線程(針對每個UIDocument)並且應用程序掛起。

我重載「saveToUrl:forSaveOperation:completionHandler:」方法我的自定義UIDocument(以避免在保存併發線程文檔):

- (void)saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^)(BOOL))completionHandler { 
NSError *contentsError = nil; 
NSError *attributesError = nil; 
NSError *savingError = nil; 

[self writeContents:[self contentsForType:self.fileType error:&contentsError] andAttributes:[self fileAttributesToWriteToURL:url forSaveOperation:saveOperation error:&attributesError] safelyToURL:url forSaveOperation:saveOperation error:&savingError]; 

NSLog(@"SAVING ERRORS: contents error - %@, attributes error - %@, saving error - %@",[contentsError localizedDescription], [attributesError localizedDescription], [savingError localizedDescription]); 
} 

然後我用我自己的序列隊列執行所有保存操作。 首先,你需要添加像伊娃:

dispatch_queue_t mySerialQueue; 

然後在init()方法創建它:

myCustomQueue = dispatch_queue_create("com.whatever.MyAwesomeQueue", DISPATCH_QUEUE_SERIAL); 

用它來保存:

dispatch_async(mySyncQueue, ^{ 
    // do saving stuff 
}); 

,然後再釋放in dealloc:

dispatch_release(mySyncQueue); 

在這個變化之後,我沒有任何問題。

希望這會有所幫助! (並對我的英語感到抱歉:>)

1

德米特里,你重寫saveToURL的方式:是不安全的。 UIDocument saveToURL的默認實現將使用文件協調來確保無處不在的守護進程知道您在寫入磁盤的時間和時間。你的實現沒有文件協調,除非你在writeContents中進行文件協調:,(你不應該這樣做)。

見UIDocument的saveToURL文檔的討論部分在:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocument_Class/UIDocument/UIDocument.html#//apple_ref/occ/instm/UIDocument/saveToURL:forSaveOperation:completionHandler