2010-06-08 56 views
3
- (void)setFirstName:(NSString*)firstNameValue { 
    [self willChangeValueForKey:@"firstName"]; 
    [firstName release]; 
    firstName = firstNameValue; 
    [firstName retain]; 
    [self didChangeValueForKey:@"firstName"]; 
} 

是嗎?因此,willChange ... foobar didChange ...塊會導致KVO通知被觸發?如果我想編寫自己的符合KVO的setter方法,它會看起來像這樣嗎?

+0

爲什麼不使用合成屬性? – kennytm 2010-06-08 11:01:44

+0

因爲我想了解幕後發生的事情。 – dontWatchMyProfile 2010-06-08 14:59:39

+0

這將是一個非常糟糕的,泄漏的@屬性(分配)'設置 - 可能包括你試圖模仿的問題? – mvds 2010-07-17 17:48:52

回答

12

不,您的實施不是100%正確的。想想看,如果firstName當前設置爲NSString實例,並且該設置器將與該相同的實例一起調用,會發生什麼情況。首先你會釋放實例,而不是你設置實例變量,在這種情況下不會改變任何東西,並且你試圖保留實例,但到那時它已經可以很好地處理了。

它應該是:

- (void)setFirstName:(NSString*)firstNameValue { 
    [self willChangeValueForKey:@"firstName"]; 
    [firstNameValue retain]; 
    [firstName release]; 
    firstName = firstNameValue; 
    [self didChangeValueForKey:@"firstName"]; 
} 

或:

- (void)setFirstName:(NSString*)firstNameValue { 
    if (firstNameValue != firstName) { 
     [self willChangeValueForKey:@"firstName"]; 
     [firstName release]; 
     firstName = firstNameValue; 
     [firstName retain]; 
     [self didChangeValueForKey:@"firstName"]; 
    } 
} 

後者的版本有,如果該值沒有真正改變不發送oberserver的通知的額外優勢。

+0

除了第一種情況下的順序和第二種情況下的禁止操作檢查之外,在您的實現方面沒有區別。你的投票是不公平的。保留後跟賦值與分配然後保留你在非操作示例中做的效果相同。最重要的是setter方法根據所需的行爲保留,分配或複製。代表和原始ivars使用分配。 – falconcreek 2010-07-16 23:52:21

+0

請記住,保留並複製返回ID,以便 [firstName release]; firstName = [firstNameValue retain]; 或 [firstName release]; firstName = [firstNameValue copy]; 根據所需的行爲將做的伎倆。 – falconcreek 2010-07-17 00:18:01

+1

@falconcreek:您沒有閱讀我的答案。當你想保留firstNameValue時可能已經被處理。 – tonklon 2010-07-17 06:08:18

0

- 致電didChangeValueForKey:將通知所有觀察員該值已更改。

相關問題