options是KVO中常見的參數(shù)捎迫,然而通常只是將它固定為“NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld”來使用卻不知道到底這個參數(shù)有什么用统刮。由此本文通過一個例子來描述該參數(shù)的實際表現(xiàn)。
NSKeyValueObservingOptions是options的類型(
- (void)addObserver:(NSObject *)observer
? ? ? ? ? ? ?forKeyPath:(NSString *)keyPath
? ? ? ? ? ? ? ? ?options:(NSKeyValueObservingOptions)options
? ? ? ? ? ? ? ? ? context:(void *)context
)
首先看頭文件中的定義:
typedefNS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
/* Whether the change dictionaries sent in notifications should contain NSKeyValueChangeNewKey and NSKeyValueChangeOldKey entries, respectively.
*/
NSKeyValueObservingOptionNew =0x01,
NSKeyValueObservingOptionOld =0x02,
/* Whether a notification should be sent to the observer immediately, before the observer registration method even returns. The change dictionary in the notification will always contain an NSKeyValueChangeNewKey entry if NSKeyValueObservingOptionNew is also specified but will never contain an NSKeyValueChangeOldKey entry. (In an initial notification the current value of the observed property may be old, but it's new to the observer.) You can use this option instead of explicitly invoking, at the same time, code that is also invoked by the observer's -observeValueForKeyPath:ofObject:change:context: method. When this option is used with -addObserver:toObjectsAtIndexes:forKeyPath:options:context: a notification will be sent for each indexed object to which the observer is being added.
*/
NSKeyValueObservingOptionInitial NS_ENUM_AVAILABLE(10_5,2_0) =0x04,
/* Whether separate notifications should be sent to the observer before and after each change, instead of a single notification after the change. The change dictionary in a notification sent before a change always contains an NSKeyValueChangeNotificationIsPriorKey entry whose value is [NSNumber numberWithBool:YES], but never contains an NSKeyValueChangeNewKey entry. You can use this option when the observer's own KVO-compliance requires it to invoke one of the -willChange... methods for one of its own properties, and the value of that property depends on the value of the observed object's property. (In that situation it's too late to easily invoke -willChange... properly in response to receiving an -observeValueForKeyPath:ofObject:change:context: message after the change.)
When this option is specified, the change dictionary in a notification sent after a change contains the same entries that it would contain if this option were not specified, except for ordered unique to-many relationships represented by NSOrderedSets.For those, for NSKeyValueChangeInsertion and NSKeyValueChangeReplacement changes, the change dictionary for a will-change notification contains an NSKeyValueChangeIndexesKey (and NSKeyValueChangeOldKey in the case of Replacement where the NSKeyValueObservingOptionOld option was specified at registration time) which give the indexes (and objects) which *may* be changed by the operation.The second notification, after the change, contains entries reporting what did actually change.For NSKeyValueChangeRemoval changes, removals by index are precise.
*/
NSKeyValueObservingOptionPrior NS_ENUM_AVAILABLE(10_5,2_0) =0x08
};
可以很清楚的看到污抬,其中包含了四種值汞贸,分別為:
NSKeyValueObservingOptionNew:提供更改前的值
NSKeyValueObservingOptionOld:提供更改后的值
NSKeyValueObservingOptionInitial:觀察最初的值(在注冊觀察服務(wù)時會調(diào)用一次觸發(fā)方法)
NSKeyValueObservingOptionPrior:分別在值修改前后觸發(fā)方法(即一次修改有兩次觸發(fā))
以下是一個簡單的測試案例:
測試代碼
將options修改為NSKeyValueObservingOptionNew得到測試結(jié)果:
2016-07-04 19:18:29.265 testForKVO[50887:35316085] turn1
2016-07-04 19:18:29.265 testForKVO[50887:35316085] ? ?kind: 1
2016-07-04 19:18:29.266 testForKVO[50887:35316085] ? ?new: turn1
2016-07-04 19:18:29.266 testForKVO[50887:35316085] turn2
2016-07-04 19:18:29.266 testForKVO[50887:35316085] ? ?kind: 1
2016-07-04 19:18:29.266 testForKVO[50887:35316085] ? ?new: turn2
可以看到觀察被觸發(fā)2次,在change對象中包含key為new的值印机,并且為stringA的最新值
將options修改為NSKeyValueObservingOptionOld得到測試結(jié)果:
2016-07-04 19:19:14.562 testForKVO[50912:35317211] turn1
2016-07-04 19:19:14.562 testForKVO[50912:35317211] ? ?kind: 1
2016-07-04 19:19:14.562 testForKVO[50912:35317211] ? ?old: turn0
2016-07-04 19:19:14.563 testForKVO[50912:35317211] turn2
2016-07-04 19:19:14.563 testForKVO[50912:35317211] ? ?kind: 1
2016-07-04 19:19:14.563 testForKVO[50912:35317211] ? ?old: turn1
可以看到觀察被觸發(fā)2次矢腻,在change對象中包含key為old的值,并且為stringA被修改前的值
將options修改為NSKeyValueObservingOptionInitial得到測試結(jié)果:
//注冊觀察服務(wù)時
2016-07-04 19:20:08.003 testForKVO[50938:35318482] turn0
2016-07-04 19:20:08.004 testForKVO[50938:35318482] ? ?kind: 1
//self.stringA=@"turn1";
2016-07-04 19:20:08.004 testForKVO[50938:35318482] turn1
2016-07-04 19:20:08.004 testForKVO[50938:35318482] ? ?kind: 1
//self.stringA=@"turn2";
2016-07-04 19:20:08.004 testForKVO[50938:35318482] turn2
2016-07-04 19:20:08.005 testForKVO[50938:35318482] ? ?kind: 1
可以看到觀察被觸發(fā)3次耳贬,在觀察服務(wù)注冊時踏堡,執(zhí)行了一次觸發(fā)
將options修改為NSKeyValueObservingOptionPrior得到測試結(jié)果:
2016-07-04 19:20:47.936 testForKVO[50962:35319521] turn0
2016-07-04 19:20:47.937 testForKVO[50962:35319521] ? ?kind: 1
2016-07-04 19:20:47.937 testForKVO[50962:35319521] ? ?notificationIsPrior: 1
2016-07-04 19:20:47.937 testForKVO[50962:35319521] turn1
2016-07-04 19:20:47.937 testForKVO[50962:35319521] ? ?kind: 1
2016-07-04 19:20:47.937 testForKVO[50962:35319521] turn1
2016-07-04 19:20:47.938 testForKVO[50962:35319521] ? ?kind: 1
2016-07-04 19:20:47.938 testForKVO[50962:35319521] ? ?notificationIsPrior: 1
2016-07-04 19:20:47.938 testForKVO[50962:35319521] turn2
2016-07-04 19:20:47.938 testForKVO[50962:35319521] ? ?kind: 1
可以看到觀察被觸發(fā)4次,從turn0->turn1改變前后觸發(fā)2次咒劲,turn1->turn2改變前后觸發(fā)2次
其它
將options修改為 0 得到測試結(jié)果:
2016-07-04 19:50:43.925 testForKVO[51293:35351701] turn1
2016-07-04 19:50:43.925 testForKVO[51293:35351701] ? ?kind: 1
2016-07-04 19:50:43.925 testForKVO[51293:35351701] turn2
2016-07-04 19:50:43.925 testForKVO[51293:35351701] ? ?kind: 1
將options修改為
NSKeyValueObservingOptionNew|
NSKeyValueObservingOptionOld|
NSKeyValueObservingOptionInitial|
NSKeyValueObservingOptionPrior得到測試結(jié)果:
//注冊觀察服務(wù)時
2016-07-04 19:33:12.326 testForKVO[51133:35333070] turn0
2016-07-04 19:33:12.326 testForKVO[51133:35333070] ? ?kind: 1
2016-07-04 19:33:12.326 testForKVO[51133:35333070] ? ?new: turn0
//self.stringA=@"turn1";
2016-07-04 19:33:12.327 testForKVO[51133:35333070] turn0
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?kind: 1
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?old: turn0
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?notificationIsPrior: 1
2016-07-04 19:33:12.327 testForKVO[51133:35333070] turn1
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?kind: 1
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?old: turn0
2016-07-04 19:33:12.327 testForKVO[51133:35333070] ? ?new: turn1
//self.stringA=@"turn2";
2016-07-04 19:33:12.328 testForKVO[51133:35333070] turn1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?kind: 1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?old: turn1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?notificationIsPrior: 1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] turn2
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?kind: 1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?old: turn1
2016-07-04 19:33:12.328 testForKVO[51133:35333070] ? ?new: turn2
參考資料:
00000002