2011-11-02 61 views
3

我遇到了一個問題,即獲取類型爲id的對象。我知道它的基類型是一個NSManagedObject,但實際上它的實際類型(名稱,電子郵件等)的自定義屬性是我真正需要的。從長遠來看,我試圖讓一個方法,將我的自定義NSManagedObjects到NSDictionaries。也許我下去一般,但走錯了路....基於NSString類名鑄造對象的客觀c類型

如果我有像

-(void)someMethod:(id)obj{ 
... 
Class someClass = NSClassFromString([[obj class] description]); 
... 

我可以從獲取類,但後來我真的不能弄清楚如何施展我的對象作爲那個班級。

理想,這將是該代碼

someClass* myObject = (someClass*)obj; 
NSArray *keys = [[[myObject entity] attributesByName] allKeys]; 
NSDictionary *dict = [myObject dictionaryWithValuesForKeys:keys]; 
//do something with dict 
... 

的接下來的幾行,但我無法弄清楚如何獲得類型SomeClass的對象。我所看到的,你可以使用NSClassFromString對象的頁頭初始化調用,比如

id someObject = [[className alloc] init]; 

但不會出現這種情況工作,因爲我已經在我需要傳遞的對象。任何想法/批評?我真的想盡量避免所有我的項目,如果陳述的廢話加載,但它可能是現在最快的方式...

+0

我想問一個更好,更簡潔的問題(sans代碼示例)的方法是:是否有動態的方式來傳入NSManagedObject作爲其子類的自定義對象,並從中獲取所有字段的NSDictionary我的自定義對象? – AtomRiot

+2

爲什麼你覺得你需要投入一些動態類型? Objective-C是動態類型的,與編譯器語法檢查器不同(與編譯器語法檢查器不同),當您撥打電話時會使用什麼類型的指針 - 哎呀,請原諒 - 「發送消息」。 –

回答

3

如果它們都是NSManagedObject子類,並且您將調用它們的所有值都是valueForKey或NSManagedObject實現的其他方法,只需轉換爲NSManagedObject即可。如果我錯過了什麼,請告訴我。

在回答關於原來的問題您的評論 - 你已經有了這個您的樣品中:

NSDictionary *myObjectDictionary = [[myObject entity] attributesByName]; 

這給你包含你的管理對象的所有屬性的字典,帶有屬性名稱作爲關鍵在每種情況下。然後,您可以使用這些鍵在對象上調用valueForKey。

也許我需要做的一點是,如果您不打算調用任何子類特定的方法,那麼將對象作爲其超類就可以。

+0

我有NSManagedObject子類的自定義類。在那些自定義類中,我需要字典鍵。 – AtomRiot

+0

好的,那些不僅僅是來自數據模型的屬性? – jrturton

+0

不,它們是來自數據模型的屬性,只是我試圖對我所有的自定義類使用此方法來轉換將其傳遞給字典的對象。 – AtomRiot

0

這個問題有點混淆,但你在尋找isKindOfClass:方法嗎?

NSObject Reference

NSMutableData *myData = [NSMutableData dataWithCapacity:30]; 
id anArchiver = [[NSArchiver alloc] initForWritingWithMutableData:myData]; 
if ([anArchiver isKindOfClass:[NSCoder class]]) 
    ... 

此外,您鑄造正常。這是將對象強制轉換爲類型MyClass正確的方法:

MyClass *myObject = (MyClass *)obj; 

如果沒有在這裏幫助你能證明你正在或什麼不正常的錯誤?

+0

我認爲他的問題是他想要訪問一堆對象的屬性,但是如果不先確定它的類並投射指針,他就無法做到這一點。 – CharlieMezak

+0

不,我正在尋找不必做一個「廢話加載的if語句」來確定(通過isKindOfClass:)對象的類。顯然,使用NSClassFromString生成的類不能用於此方法。這不是一個普通的課程。 – AtomRiot

0

嚴格地說,我不認爲你可以在Obj-C中投射一個對象,但是你可以把指針指向另一個類(這可能是你的意思,對不起,挑剔)。

我不知道隨便如何處理的編程聰明的方式鑄造,但如果你有一個類的合理數量的,你可以只使用條件塊來處理不同的情況:

if ([obj isMemberOfClass:[MyClass class]]) { 
    ... 
} else if ([obj isMemberOfClass:[MyOtherClass class]]) { 
... 
} 

如果每個塊中的代碼大部分(甚至部分)都是相同的,你可以隨時在NSManagedObject和包含公共代碼的類之間添加一個超類,所以你可以將指針投射到該超類,處理常見的東西,如果有必要的話,仍然會潛入條件。

我確定有人會用更聰明的答案突襲,但我的想法。祝你好運!

+0

將我的自定義NSManagedObjects分開的事情是它們之間的不同屬性。我想到做超級班的路線,但後來才意識到,我會在不同的地方有同樣的問題。我認爲最好的路線是當對象需要這種方法時,只是將字典傳遞到創建的方法中,而不是對象本身。這樣我可以保證我需要的屬性在那裏。 – AtomRiot

+0

如何使用respondsToSelector測試屬性是否可用? – CharlieMezak

1

如果您唯一的目標是將對象(id)轉換爲字典。既然你說,你知道他們是NSManagedObject任何情況下,你可以放心地投它:

- (void)someMethod:(id)object { 
    NSManagedObject* managedObject = (NSManagedObject *)object; 

其實,如果你想成爲它生硬,這可能被更改爲:

- (void)someMethod:(NSManagedObject *)managedObject { 

如果你聲明瞭這個方法。

您可以通過訪問它的實體訪問被管理對象的元數據:

NSEntityDescription *entity = [managedObject entity]; 

從那裏,獲取每個屬性的說明:

NSDictionary *descriptions = [entity propertiesByName]; 

這本詞典將所有的按鍵你想在你的字典中,並且NSAttributeDescriptionNSRelationshipDescription作爲值。

事實上,你已經寫了自定義類來提供這些類的功能是無關緊要的!您可以訪問它們中的所有數據,而不管它們是否爲NSManagedObject實例或其子類。