2011-12-04 26 views
1

使用@synthesize生成的setter是KVC compilant還是不是?我發現getter和setter生成的聲明符合KVC,不應該調用這種方法嗎?@合成屬性和KVC

@interface testing : NSObject 
@property (nonatomic, retain) NSString *phone; 
@end 

實現:

@implementation testing 
@synthesize phone; 

- (id)init { 
    self = [super init]; 
    return self; 
} 

// none of these is called with dot syntax, or setter setPhone 
- (void)setValue:(id)value forKey:(NSString *)key 
{ 
    NSLog(@"%@",key); 
    [super setValue:value forKey:key]; 
} 

-(void)setValue:(id)value forKeyPath:(NSString *)keyPath 
{ 
    NSLog(@"%@",keyPath); 
    [super setValue:value forKeyPath:keyPath]; 
} 

@end 

,並對其進行測試:

testing *t = [[testing alloc] init]; 
[t setPhone:@"55555555"]; 

回答

8

我認爲你錯了。符合KVC並不意味着訪問者會打電話-setValue:forKey:符合KVC意味着調用-setValue:forKey:將調用訪問者。

有點擴大:KVC標準只意味着'如下命名約定'。爲什麼這很重要?我可以調用我喜歡的訪問器方法。對於屬性'Foo':

- (void)weakSetFoo:(id)f; 
- (id)autoreleasedFoo; 

這很好。但是,像綁定的機制將嘗試通過調用

[ob setValue:newVal forKey:@"foo"]; 

-setValue:forKey:設置美孚將嘗試做正確的事,並使用訪問方法(如果我們寫了一個setter方法,這是因爲我們希望它被使用,正確的?)。但是,除非我們將制定者方法命名爲標準-setFoo:,否則將無法找到它。

所以-weakSetFoo:是一個setter方法,但屬性Foo不符合KVC。 如果我將設置者名稱更改爲-setFoo:,則Foo屬性現在與KVC兼容。

默認情況下,合成存取器方法將被正確命名。

2

你並不需要實現setValueForKey:爲志願。它在框架內爲您實施。通過使您的屬性志願兼容(您已使用@property和@synthesize完成),一切都只是工作「神奇」

-----更新

另外,你的測試代碼不考志願。要測試它,請執行如下操作:

testing *t = [[testing alloc] init]; 
[t setValue:@"55555555" forKey:@"phone"]; 
+0

我正在測試生成的setter是KVO compilant的語句,這就是爲什麼我使用setter,而不是setValue itselt。我知道調用setValue的工作,但調用生成的setter不會在「測試」上調用setValue。 – Marcin

2

實際上這是相反的方式。 這些是setValue:forKeygetValueforKey,它們查找符合KVC的屬性,而不是通過它們合成的屬性。

當你編寫@synthesize property時,編譯器實際上只是填充- (type) property- (void) setProperty: (type)value類型的讀取/設置相應實例變量的方法。