這是我在Stack Overflow上的第一個問題,所以請原諒我打破任何禮節。我也是相當新的Objective-C /應用程序創建。UIManagedDocument在後臺線程中插入對象
我一直在關注CS193P斯坦福大學課程,特別是CoreData講座/演示。在Paul Hegarty的Photomania應用程序中,他從一個表視圖開始,並在後臺填充數據,而不會中斷UI流。我一直在創建一個列出當地業務的應用程序(來自返回JSON數據的api)。
我已經根據Paul的照片/攝影師課程創建了類別。類的創建本身不是問題,它是創建它們的地方。
我的應用程序開始與幾個按鈕一個UIViewController,其中的每一個可以打開相應部分中的實現代碼如下(所有這些做工精細,我想提供足夠的信息讓我的問題是有道理的)。我調用一個幫助器方法來創建/打開基於this question的UIManagedDocument的URL。只要應用程序運行,就會調用它,並且它會很快加載。
我有非常類似保羅的fetchFlickrDataIntoDocument的方法:
-(void)refreshBusinessesInDocument:(UIManagedDocument *)document
{
dispatch_queue_t refreshBusinessQ = dispatch_queue_create("Refresh Business Listing", NULL);
dispatch_async(refreshBusinessQ, ^{
// Get latest business listing
myFunctions *myFunctions = [[myFunctions alloc] init];
NSArray *businesses = [myFunctions arrayOfBusinesses];
// Run IN document's thread
[document.managedObjectContext performBlock:^{
// Loop through new businesses and insert
for (NSDictionary *businessData in businesses) {
[Business businessWithJSONInfo:businessData inManageObjectContext:document.managedObjectContext];
}
// Explicitly save the document.
[document saveToURL:document.fileURL
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success){
if (!success) {
NSLog(@"Document save failed");
}
}];
NSLog(@"Inserted Businesses");
}];
});
dispatch_release(refreshBusinessQ);
}
[myFunctions arrayOfBusinesses]剛剛解析JSON數據,並返回一個包含個人businessses一個NSArray。
我已經在業務創建代碼的開始和結束處使用NSLog運行代碼。每個企業都分配了一個部分,需要0.006秒才能創建,並且有幾百個這樣的部分。插入結束大約需要2秒鐘。
輔助方法是在這裏:
// The following typedef has been defined in the .h file
// typedef void (^completion_block_t)(UIManagedDocument *document);
@implementation ManagedDocumentHelper
+(void)openDocument:(NSString *)documentName UsingBlock:(completion_block_t)completionBlock
{
// Get URL for document -> "<Documents directory>/<documentName>"
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:documentName];
// Attempt retrieval of existing document
UIManagedDocument *doc = [managedDocumentDictionary objectForKey:documentName];
// If no UIManagedDocument, create
if (!doc)
{
// Create with document at URL
doc = [[UIManagedDocument alloc] initWithFileURL:url];
// Save in managedDocumentDictionary
[managedDocumentDictionary setObject:doc forKey:documentName];
}
// If the document exists on disk
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[doc openWithCompletionHandler:^(BOOL success)
{
// Run completion block
completionBlock(doc);
} ];
}
else
{
// Save temporary document to documents directory
[doc saveToURL:url
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
// Run compeltion block
completionBlock(doc);
}];
}
}
,被稱爲在viewDidLoad中:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocument只設置self.document所提供的文件。
我想更改此代碼,以便將數據插入到另一個線程中,並且用戶仍然可以單擊按鈕查看某個部分,而不會導致數據導入掛起UI。
任何幫助,將不勝感激我已經在這個問題上工作了幾天,並沒有能夠解決它,即使在這裏的其他類似的問題。如果您需要其他信息,請告訴我!
謝謝
編輯:
到目前爲止,這個問題已經收到一個向下票。如果有什麼方法可以改善這個問題,或者有人知道我找不到的問題,請您評論一下如何或在哪裏?如果您還有其他原因會導致投票失敗,請讓我知道,因爲我無法理解這種消極情緒,並且很想學習如何提供更好的貢獻。
你是一個絕對的傳奇!我已經使用你的第一個解決方案,對我來說,它似乎更容易理解。不幸的是,我不能給你這樣的享受,因爲我只是剛剛加入,但當我可以的時候我會。 我會在晚些時候看看NSOperations,因爲這讓我有點困惑。再次感謝您的幫助! –
不客氣。乾杯。 –
只是爲了完成:不要忘記告訴你的UIManagedDocument它在你的(和其他)操作後處於一個骯髒的狀態。所以通過調用'[document updateChangeCount:UIDocumentChangeDone]'來強制保存。這是CS193P斯坦福大學課程中缺少的。 –