很久之前寫了一份傳值的文章- 傳值
里面記錄了方法傳值扰法,代理蛹含,通知以及Block傳值。
不夠全面迹恐,還有KVO沒有介紹挣惰,在這里補上,同時比對一下各自的不同
KVO(key-value-observing鍵值觀察)
把對象的某個屬性作為鍵殴边,當(dāng)鍵的值改變時,就會喚起響應(yīng)方法珍语。實現(xiàn)KVO锤岸,要先添加監(jiān)聽
<#observer#>監(jiān)聽的對象
<#keyPath#>監(jiān)聽的對象屬性
<#options#>監(jiān)聽的類型
<#context#>傳入的上下文對象
添加了監(jiān)聽之后,我們需要響應(yīng)監(jiān)聽
<#keyPath#>監(jiān)聽的屬性
<#object#>監(jiān)聽的對象
<#change#>改變的值板乙,從上面的注釋來看是偷,change里的值拳氢,跟設(shè)置監(jiān)聽時傳入的option有關(guān)。
當(dāng)你在設(shè)置監(jiān)聽時,option選擇了<NSKeyValueObservingOptionNew>,此處就會返回新的值蛋铆,當(dāng)設(shè)置了<NSKeyValueObservingOptionOld>,此處返回改變前的值馋评,當(dāng)你兩種都傳入時,我們就可以拿到改變前的值跟改變后的值
<#context#>上下文對象刺啦,從上方注釋來看留特,context對象永遠是你注冊監(jiān)聽時傳入的相同上下文對象
上代碼
@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;
}
結(jié)果如下,如此玛瘸,就完成了基本的監(jiān)聽蜕青,當(dāng)然,別忘了移除監(jiān)聽
KVO的介紹到此為止。接下來比對一下各自的區(qū)別糊渊。
-
KVO:監(jiān)聽對象右核,對象屬性變化時,接收信息渺绒,可以看到屬性的變化過程
-
通知:在通知中心簽署通知贺喝,通知中心根據(jù)簽署的通知名稱,發(fā)出消息到所有簽署對應(yīng)通知的對象上宗兼,一對多搜变,不保證所有簽署者都可以收到通知
-
代理:雇主不做事,由代理去處理響應(yīng)方法针炉。代理屬性使用weak屬性挠他,不增加內(nèi)存,但如果方法多的話篡帕,會有大量的方法實現(xiàn)代碼
- 代理簽署協(xié)議
- 判斷是否實現(xiàn)協(xié)議方法
- 實現(xiàn)協(xié)議方法
-
block:類似于方法函數(shù)殖侵,使用copy來定義,會引起內(nèi)存增加,需要注意循環(huán)引用問題.