2010-06-11 111 views
0

我的核心數據是新的,和我有一個問題,我不能讓我圍繞着如何做「正確的方式」綁定到一個核心屬性的關係數據

我會盡力和examplify頭我的問題。

我得到了一個實體車。還有我的程序中的所有汽車的列表。汽車有一些屬性,但它們不是預定義的。所以對於每輛車我都希望能夠定義一些屬性。 因此,我定義了一個新的實體CarProperty,與汽車有一對多的關係。

在nscollectionview中,我想展示汽車的一些屬性,更具體說明它驅動的公里數(numKm)(如果該屬性存在)。所以我想將它綁定到一個標籤。但怎麼辦?

我不能說representedObject.properties.numKmrepresentedObject.numKm

我該如何解決這個問題?

,真希望是有道理的。

回答

1

這不是一個簡單的問題。事情是,Core Data不知道numKm作爲一個屬性。它應該如何知道numKm對應於特定的CarProperty對象?

您正在描述的基本問題是鍵值編碼合規性。 Cocoa將在properties對象上尋找一種叫做numKm的方法。沒有找到一個,它會嘗試發送[properties valueForKey:@"numKm"];由於valueForKey:不知道該怎麼做numKm,你會得到一個錯誤,而不是它調用[properties valueForUndefinedKey:@"numKm"]

但這裏的漁獲前:properties是核心數據生成的NSSet ,所以你不能繼承它來覆蓋valueForUndefinedKey:。你可以做的是創建你自己的對象,它符合你的任意屬性的KVC標準並使用它。

一種解決方案是將子類NSDictionary並使其充當代理。原始方法是countobjectForKey: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發生變化,您將無法觀察到這一點。你需要做一些額外的工作才能做到這一點。

+0

非常感謝!這使我非常喜歡一個方向!很高興知道我不會通過簡單的解決方案重新解決常見問題。 – 2010-06-12 10:24:20

+0

這個答案是完全正確的,但是,我不得不問,爲什麼你使用Core Data只是爲了拋棄它的權力?如果你有一個汽車實體,有些事情應該是屬性,其他事情應該是關係。例如,numKm應該是float或int,因爲它很可能不會經常在汽車之間重複。另一方面,製造商應該完全是與製造商實體的關係。您甚至可以使用綁定來查看特定製造商的所有汽車。 – theMikeSwan 2010-06-16 01:32:43

+0

我不能說OP的情況,但在我的情況下,屬性直到運行時才知道。我的應用程序從Web服務器下載對象列表,其中列表可以具有任意類型的任意列。除了保證存在的一些屬性以及我爲其創建屬性外,其餘所有屬性在數量和類型上都是可變的。 – Alex 2010-06-16 14:54:58