2009-08-04 54 views
2

我在覈心數據的一個方面略有困惑。也就是說,我什麼時候使用基本的alloc/init例程來創建一個包含核心數據的對象並將其保存到當前的託管對象上下文中。使用核心數據時的模型實例化問題

我知道這是一個相當模糊的問題,所以讓我舉個例子。

我有一個應用程序,我目前正在對iPhone上的所有用戶通訊錄進行迭代。從那裏,我寫了一個名爲'人'的模型班。我曾經在一個循環中做這樣的事情:

Person * person = [[Person alloc] initWithWrapper:mywrapper];

mywrapper將包含一個NSDictionary與人的屬性。之後,我可以使用個人對象在我的應用中填充地址簿。

現在我已經開始使用Core Data重建部分應用程序。我是否繼續使用上述策略填充我的地址簿?或者我會這樣做:

Person *person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; 

    [person setName:name]; 
    [person setDob:dob]; 

    // Commit the change. 
    NSError *error; 
    if (![managedObjectContext save:&error]) { 
     // Handle the error. 
    } 

問題是,每次應用程序啓動時都會執行此代碼。我是否應該不使用核心數據,因爲每次應用程序加載時都會使用冗餘實例來填充存儲機制?我應該修改我的NSManagedObject(Person類)並添加我的initWithWrapper:方法並繼續像我平常那樣嗎?

有點困惑,會喜歡澄清。

回答

4

您不應該在託管對象上下文之外初始化核心數據對象 - 這根本就沒有意義。有一些

Person *person = [[[Person alloc] init] autorelease];

對你沒有好,因爲你不能保存對象,操作它,或真的做任何核心數據提供了有用的無上下文(因此模型和存儲協調人)進行備份。

當您首次將對象插入Core Data時,您應該只使用alloc - init組合;這是initWithEntity:insertIntoManagedObjectContext:方法的用途。你說得對,每次你調用這個方法時,你都會在Core Data上下文中插入一個新的對象,因此存儲,如果你不小心的話,你可能會得到重複的對象。

如果您在每次啓動時運行代碼,我會推薦給您的是提出一個核心數據查詢,該查詢返回一組現有的Person對象,並且只添加對象(使用初始化方法)這在商店中尚不存在。如果對象已經存在,請修改它而不是創建一個新對象。

訣竅是讓這樣的東西正常執行。您不應該爲iPhone地址簿中的每個聯繫人執行核心數據提取;許多這樣的小提取都非常昂貴。理論上你可以得到兩個NSSets--一個Person對象和一個聯繫人 - 然後通過一些唯一鍵(比如聯繫人的姓和名)來比較它們。我把優化留給你。

的關鍵點是這樣的:沒有核心數據對象使用allocinit除非你的意思是插入的第一次該對象到上下文。相反,看看你現有的對象,並在必要時修改它們。

0

是的,將initWithWrapper方法添加到Person類是最簡單的。這將是這樣的:

- (id) initWithWrapper:(NSDictionary *)wrapper { 
    NSEntityDescription * person = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:someMOC]; 
    if (self = [super initWithEntity:person insertIntoManagedObjectContext:someMOC]) { 
    //do your wrapperly initialization here 
    } 
    return self; 
} 

唯一的缺點是,這方法有知道哪些managedObjectContext應該將對象插入,所以你必須想出一個辦法來提供。

這就是說,我一直都在使用這種模式。

+0

因此,每次應用程序啓動時,您仍然將person對象添加到managedObjectContext中?如果每個對象始終都是同一個人開始?這不會在數據存儲中複製Person對象嗎? – Coocoo4Cocoa 2009-08-04 01:35:58

+0

@ Coocoo4Cocoa爲什麼不只是執行謂詞爲「name =%@」的提取請求並查看它是否在添加新人之前返回任何結果? – 2009-08-04 01:45:23