2014-04-01 52 views
0

在我的項目,我應該下載這樣做了一個JSON文件:的iOS:更新核心數據DB需要大量的時間

[{"id":"2","n":"One"},{"id":"2","n":"Two"},{"id":"2","n":"Three"},...] 

我的代碼是這樣的:

- (void) startPopulate:(NSArray *)array{ 

    NSManagedObjectContext *context = [[self sharedAppDelegate] managedObjectContext]; 

    NSFetchRequest *fetchRequest=[NSFetchRequest fetchRequestWithEntityName:@"Myentity"]; 
    NSError *error = nil; 

    for (id element in array){ 

     [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"id == %@",[element objectForKey:@"id"]]]; 
     Myentity *myE = [[context executeFetchRequest:fetchRequest error:&error] lastObject]; 

     //update 
     if (myE != nil){ 

      myE.id_e = [element objectForKey:@"id"]; 
      myE.name = [element objectForKey:@"n"]; 
     } 

     //new element 
     else{ 

      Myentity *myE = [NSEntityDescription insertNewObjectForEntityForName:@"Myentity" inManagedObjectContext:context]; 
      myE.name = [element objectForKey:@"n"]; 
      myE.id_e = [element objectForKey:@"id"]; 
     } 
    } 

    if (![context save:&error]) { 
     NSLog(@"couldn't save: %@", [error localizedDescription]); 
    } 
    else{ 

     NSLog(@"DB UPDATED"); 
    } 
} 

正如你可以看到我在方法中傳遞字典數組,並檢查實體是否存在。 它工作正常,我沒有詳細的問題。 '問題',如果它是調用它的方式是,我有12000元素,這種方法運行約53秒。這非常慢。 我可以採用什麼類型的解決方案來提高速度? 或者我應該把這個方法放在後臺進程中? 謝謝

+1

有一些[Apple的文檔中描述的技術](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html)可以幫助你。 – Alladinian

+0

可能的重複[什麼是最有效的方式來同步核心數據與JSON API](http://stackoverflow.com/questions/14109501/what-is-the-most-efficient-way-to-sync-core- data-with-json-api) –

回答

0

你應該把它放在後臺進程嗎?

絕對。啓動一個後臺線程並創建你的主上下文孩子方面做所有的工作。

還有什麼可以做

您對管理對象上下文中,每個未保存的更改被保存在內存中。在保存前進行數千次更改是不可取的,因爲它會佔用大量內存,但保存過程也需要很長時間。

你可以批量更新到發言權100個變化的時間,節省100

每個塊替代

如果你總是在加載這些項目的應用程序,然後你也可以預載他們到一個數據庫,並將其捆綁到應用程序本身。

這樣你就不需要在運行時保存它們,因爲它們已經在那裏了。

+0

你有什麼建議用核心數據創建後臺線程嗎? – CrazyDev

0

這裏是同時使用的核心數據如何創建一個後臺線程:

dispatch_queue_t fetchQ = dispatch_queue_create("JSON Fetcher", NULL); 
    dispatch_async(fetchQ, ^{ 
     NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     context.parentContext = self.mainMOC; 

     [context performBlock:^{ 
      // implement your own background code here 

      NSError *error; 
      if(![context save:&error]) { 
       // handle error 
      } 
     }]; 
}); 

您還需要保存結果,使他們得到傳播到mainMOC。希望能幫助到你!