iOS 代理和block
做iOS三年了,平時開發程序中經常用到代理和block,兩者即有相同的作用——都可以實作回呼的作用,下面對兩著做一些總結和對比,
代理
示例:有物件A:視圖控制器、物件B:A的子控制元件TableView
·A是代理物件,B是被代理物件
·A要參考B
·A需要遵守協議,并且實作協議里面規定的方法
·B通過委托方法通知
Block
在iOS中block有三種
1.全域的靜態block,不訪問任何外部變數,執行完即回收
^{
NSLog(@"Hello World!");
}();
2.保存在堆疊中的 block,當函式回傳時會被銷毀,和第一種的區別就是呼叫了外部變數,
//UIView影片
[UIView animateWithDuration:3 animations:^{
self.view.backgroundColor = [UIColor redColor];
}];
3.保存在堆中的 block,當參考計數為 0 時會被銷毀,例如按鈕的點擊事件,一直存在,即使執行過,也不銷毀,因為按鈕還可能被點擊,持有按鈕的View被銷毀,它才會被銷毀,
#import <UIKit/UIKit.h>
typedef void(^ButtonClickBlcok)();
@interface TestView : UIView
@property (nonatomic, copy) ButtonClickBlcok buttonClickBlcok;
@end
#import "TestView.h"
@implementation TestView
- (IBAction)buttonClick:(id)sender {
if (self.buttonClickBlcok) {
self.buttonClickBlcok();
}
}
@end
示例:有物件A、B,B產生事件,A回應事件,
·B回呼block,A傳遞block
·B需要定義block并且有一個block屬性(定義block屬性時需要用copy)
·A接收到事件傳遞block時,block里面的具體操作在這里定義,但在傳遞時不會執行,執行是在B回呼block時block執行
定義block需要用關鍵字“copy”的原因:
Block存盤在堆疊區,堆疊區的特性是當一個方法運行完成之后里面的記憶體就會釋放掉,如果block被釋放,那么后面回呼就會遇到問題,所以要把block復制到堆區來存盤,所以用copy把整個block內容拷貝過來并且在堆區新建一塊空間來存盤block,
造成回圈參考的原因:
為了blcok不被系統回收,所以我們用copy關鍵字修飾,實行強參考,block對捕獲的變數也都是強參考,所以就會造成回圈參考,
···
__weak ViewController *weakSelf = self;
_testBlock = ^{
//引發回圈參考
NSLog(@"%@", self);
//防止回圈參考
NSLog(@"%@", weakSelf);
};
···
總結:
1.代理更注重程序資訊的傳輸:比如發起一個網路請求,可能想要知道此時請求是否已經開始、是否收到了資料、資料是否已經接受完成、資料接收失敗
2.block注重結果的傳輸:比如對于一個事件,只想知道成功或者失敗,并不需要知道進行了多少或者額外的一些資訊
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/267356.html
標籤:其他
上一篇:iOS底層原理(十)架構設計
