2014-05-06 21 views
2

我很好奇,但可以使用自定義鍵(和手動更改通知)來實現KVO嗎?使用KVO與自定義鍵

因此,舉例來說,我可以這樣註冊:

[myObject addObserver:self forKeyPath:@"My custom string" options:0 context:nil]; 

,併發出這樣的變更通知:

[self willChangeValueForKey:@"My custom string"]; 
// do something 
[self didChangeValueForKey:@"My custom string"]; 

我在一個小的測試應用程序嘗試了這一點,它的工作原理,但我很好奇是否有人使用過或看過它的價值。

+0

你也可以使用NSNotificationCenter這樣的東西。 – CrimsonChris

回答

-1

我想你可以,但你是錯誤的使用機制。

如果您使用的密鑰與您正在更改的屬性不匹配,那麼提供價值信息之前和之後的通知將無法正常工作。我認爲CrimsonChris有正確的想法。如果你正在做的只是觸發一個事件,使用通知。這就是通知管理器的用途。

1

我同意,如果密鑰不對應一個屬性,你不應該使用KVO。但是,應該注意的是,屬性不需要實例變量或訪問器。您可以完全使用符合鍵值編碼的方法實現動態屬性。儘管(例如-valueForKey[Path]:-setValue:forKey[Path]:),這種財產只能通過KVC訪問。

例如,如果您實施-valueForUndefinedKey:,則可以檢查密鑰,如果它匹配動態或虛擬屬性的名稱(使用您所需的任何標準),則可以返回相應的值。同樣,如果您實施-setValue:forUndefinedKey:,則可以使該屬性爲可寫。

對於這種情況,您不一定必須發出手動KVO更改通知。當您致電-setValue:forKey[Path]:時,KVC會自動發出這些信息。但是,如果您更改了某個有效更改屬性值的內部狀態,則必須自行發出更改通知。

1

如果您的目標僅僅是通知某個事件,那麼最好只發佈一個自定義事件到NSNotificationCenter並註冊。

如果您要爲某些自定義屬性實現KVO,那麼您確實需要確保您的自定義屬性爲KVO Compliant,其中包括它應該符合KVC。由於文檔說:

爲了被認爲是國際志願者組織兼容的特定屬性,類必須確保以下幾點:

有兩種技術可以確保發出更改通知。自動支持由NSObject提供,並且默認可用於符合鍵值編碼的類的所有屬性。通常,如果您遵循標準的Cocoa編碼和命名約定,則可以使用自動更改通知 - 不必編寫任何其他代碼。

手動更改通知提供了何時發出通知的額外控制,並且需要額外的編碼。您可以通過實施類方法automaticallyNotifiesObserversForKey:來控制子類屬性的自動通知。

簡而言之,KVO比willChangeValueForKeydidChangeValueForKey要多得多。


我會建議你要麼完全實現志願(及全KVO/KVC合規性是很容易的,如果你只是合成的標準屬性;如果你想要做手工這是一個稍微複雜一點),或者不使用國際志願者組織所有,並使用其它接口,如通知中心:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotification:) name:kMyNotificationKey object:nil]; 

與控制器,如:

- (void)didReceiveNotification:(NSNotification *)notification 
{ 
    // do whatever you want here 
} 

和通知被張貼機智h:

[[NSNotificationCenter defaultCenter] postNotificationName:kMyNotificationKey object:nil];