2012-09-12 22 views
0

有人能向我解釋爲什麼這不起作用:CoreData對象類型將無法正常工作

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass]; 

NSString *myString = classObject.stringProperty; 

但這:

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass]; 
NSString *myString = [classObject valueForKey:@"stringProperty"]; 

編輯: 什麼鑄就了最簡單的方法字典作爲我NSManagedObjectClass CoreDataClass,所以我可以直接訪問屬性?

+1

您將字典轉換爲一些非常不同的類,並期望它可以工作?祝你好運! – Tom

+0

他們沒有什麼不同,班上有相同的KVC對。將符合KVC的字典轉換爲匹配的NSManagedObject類最快等待什麼? – Eric

回答

1

僅鑄造對象似乎工作(從你不會得到類型檢查錯誤的意義上說),因爲它是編譯器的提示,但它實際上並沒有改變有關指針指向的內容,所以你仍然指向一個NSDictionary。這是因爲,在一天結束時,您基本上是在指向一個指針,但告訴Xcode您可以向其發送一組不同的選擇器。

對於NSManagedObjects,從字典創建取決於幾件事情,但推薦的方法是在您的自定義類上使用NSEntityDescription和NSManagedObjectContext創建類方法,並將字典中的屬性設置爲該對象:

+(CoreDataClass *) coreDataObjectWithDictionary:(NSDictionary *) spec { 
    CoreDataClass *myInstance = [NSEntityDescription insertNewObjectForEntityForName: @"CoreDataClass" inManagedObjectContext: [myMOCProvider sharedMOC]; 
    myInstance.someProp = [spec valueForKey:@"someProp"]; 
} 
+0

所以上面的方法讓我插入一個記錄到Moclass中,所以我可以直接作爲類訪問它? – Eric

+0

它使用託管對象上下文來管理新對象與商店的關係,並使用MOC配置的* model *和* persistent store *知道要構建的內容以及如何將其插入到數據庫中。因此,最終的結果(如果您使用SQLite)是爲您的實體配置的類創建了一個新對象,並且當您保存MOC時,將在SQL存儲中插入一行。將來,您可以/應該使用NSFetchRequest而不是此方法加載該對象,該方法會複製該對象。 –

2

它不起作用,因爲KVC合規根本不是定義類或使它們可轉換的東西 - 類層次存在是有原因的,而只是確保遵守某些方法並不會神奇地使某個東西成爲完全的實例不同的階級。請記住,在點訪問語法是一個方法只發送糖,所以這兩個是相同的:

  • classObject.stringProperty
  • [classObject stringProperty]

...,顯然後者不是對於NSDictionary的實例有效(即[[NSDictionary class] instancesRespondToSelector:@selector(stringProperty)]NO)。

你的後一個例子的作品,因爲你的問題很前提的:如果事情是KVC兼容的關鍵stringProperty,你問它該鍵的值,那麼顯然你得到的東西回來。此外,NSDictionary和CoreDataClass都響應選擇器-valueForKey:,所以發送的消息實際上在運行時工作。

將兩者結合起來的最佳方式根本不是「鑄造」 - 它是在屬性層面完成所涉及數據的完整轉換。您可以考慮在CoreDataClass上創建一個自定義-initWith...方法,該方法允許您從字典中實例化其屬性,或者找到一種方法讓您的方法返回CoreDataClass的實際實例,而不是NSDictionary。

請注意,這種解決方案可能與獲取數據的「最簡單」方式有所不同,該方法有效地繼續執行您正在執行的操作並使用-valueForKey:(儘管最好不帶演員表,這是誤導性的)。