這不是一個簡單的問題。事情是,Core Data不知道numKm
作爲一個屬性。它應該如何知道numKm
對應於特定的CarProperty
對象?
您正在描述的基本問題是鍵值編碼合規性。 Cocoa將在properties
對象上尋找一種叫做numKm
的方法。沒有找到一個,它會嘗試發送[properties valueForKey:@"numKm"];
由於valueForKey:
不知道該怎麼做numKm
,你會得到一個錯誤,而不是它調用[properties valueForUndefinedKey:@"numKm"]
但這裏的漁獲前:properties
是核心數據生成的NSSet
,所以你不能繼承它來覆蓋valueForUndefinedKey:
。你可以做的是創建你自己的對象,它符合你的任意屬性的KVC標準並使用它。
一種解決方案是將子類NSDictionary
並使其充當代理。原始方法是count
,objectForKey:
和keyEnumerator
。如果您重寫這三種方法,則可以創建一個鏈接到您的Car
對象的NSDictionary
,並返回相應的CarProperty
對象。例如:
@interface PropertyProxy : NSDictionary {
}
@property (nonatomic, readonly, assign) Car *car;
- (id)initWithCar:(Car *)car
@end
@implementation PropertyProxy
@synthesize car = _car;
- (id)initWithCar:(Car *)car {
if (!(self = [super init]))
return nil;
_car = car;
return self;
}
- (NSInteger)count {
return [car.properties count];
}
- (id)objectForKey:(NSString *)key {
return [[car.properties filteredSetUsingPredicate:[NSPredicate predicateWithFormt:@"key == %@", key]] anyObject];
}
- (NSEnumerator *)keyEnumerator {
return [[car valueForKeyPath:@"properties.key"] objectEnumerator];
}
@end
然後,在你Car
類,這樣做:
@interface Car : NSManagedObject {
// other stuff
}
@property (nonatomic, readonly) NSDictionary *carProperties;
// other stuff
@end
@implementation Car
// other stuff
- (NSDictionary *)carProperties {
return [[[PropertyProxy alloc] initWithCar:self] autorelease];
}
@end
(聲明:我剛纔輸入到這個網頁瀏覽器,所以不能保證這實際上編譯:-))
正如你所看到的,這不是世界上最簡單的事情。您可以設置主要路徑是這樣的:
representedObject.carProperties.numKm;
請記住,雖然這是一個鍵值編碼標準,它不是鍵值觀察標準。所以如果numKm
發生變化,您將無法觀察到這一點。你需要做一些額外的工作才能做到這一點。
非常感謝!這使我非常喜歡一個方向!很高興知道我不會通過簡單的解決方案重新解決常見問題。 – 2010-06-12 10:24:20
這個答案是完全正確的,但是,我不得不問,爲什麼你使用Core Data只是爲了拋棄它的權力?如果你有一個汽車實體,有些事情應該是屬性,其他事情應該是關係。例如,numKm應該是float或int,因爲它很可能不會經常在汽車之間重複。另一方面,製造商應該完全是與製造商實體的關係。您甚至可以使用綁定來查看特定製造商的所有汽車。 – theMikeSwan 2010-06-16 01:32:43
我不能說OP的情況,但在我的情況下,屬性直到運行時才知道。我的應用程序從Web服務器下載對象列表,其中列表可以具有任意類型的任意列。除了保證存在的一些屬性以及我爲其創建屬性外,其餘所有屬性在數量和類型上都是可變的。 – Alex 2010-06-16 14:54:58