很久之前寫了一份傳值的文章- 傳值
里面記錄了方法傳值,代理,通知以及Block傳值。
不夠全面,還有KVO沒有介紹,在這里補上,同時比對一下各自的不同
KVO(key-value-observing鍵值觀察)
把對象的某個屬性作為鍵,當鍵的值改變時,就會喚起響應方法。實現KVO,要先添加監聽
image.png
<#observer#>監聽的對象
<#keyPath#>監聽的對象屬性
<#options#>監聽的類型
<#context#>傳入的上下文對象
添加了監聽之后,我們需要響應監聽
image.png
<#keyPath#>監聽的屬性
<#object#>監聽的對象
<#change#>改變的值,從上面的注釋來看,change里的值,跟設置監聽時傳入的option有關。
當你在設置監聽時,option選擇了<NSKeyValueObservingOptionNew>,此處就會返回新的值,當設置了<NSKeyValueObservingOptionOld>,此處返回改變前的值,當你兩種都傳入時,我們就可以拿到改變前的值跟改變后的值
<#context#>上下文對象,從上方注釋來看,context對象永遠是你注冊監聽時傳入的相同上下文對象
上代碼
@interface Student : NSObject
@property(nonatomic,copy)NSString *name;
@end
@implementation Student
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@",object);
}
- (void)dealloc {
[self removeObserver:self forKeyPath:@"name"];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
Student *stu = [Student new];
[stu addObserver:stu forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
stu.name = @"asd";
}
return 0;
}
image.png
結果如下,如此,就完成了基本的監聽,當然,別忘了移除監聽
KVO的介紹到此為止。接下來比對一下各自的區別。
-
KVO:監聽對象,對象屬性變化時,接收信息,可以看到屬性的變化過程
-
通知:在通知中心簽署通知,通知中心根據簽署的通知名稱,發出消息到所有簽署對應通知的對象上,一對多,不保證所有簽署者都可以收到通知
-
代理:雇主不做事,由代理去處理響應方法。代理屬性使用weak屬性,不增加內存,但如果方法多的話,會有大量的方法實現代碼
- 代理簽署協議
- 判斷是否實現協議方法
- 實現協議方法
-
block:類似于方法函數,使用copy來定義,會引起內存增加,需要注意循環引用問題.