Block定義
塊與函數(shù)相似缤削,是可以獲取其他函數(shù)局部變量的匿名函數(shù)涝婉。
Block寫法
(1) 無參數(shù)
void(^block名)() = ^{代碼塊};
(2)有參數(shù)
void (^block名稱)(參數(shù)列表) = ^(參數(shù)列表) { 代碼實(shí)現(xiàn)};
(3)有參數(shù) 和 返回值 的
返回類型 (^block 名稱)(參數(shù)列表) = ^(參數(shù)列表){代碼實(shí)現(xiàn)};
(4)調(diào)用block保存的代碼
block變量名(實(shí)參);
(5)typedef簡化Block的聲明、作為屬性
聲明:typedef return_type (^BlockTypeName)(var_type);
屬性: @property (nonatomic, copy) BlockTypeName blockTypeName;
Block應(yīng)用場景
1.響應(yīng)事件
2.傳遞數(shù)據(jù)
如果block訪問的外部變量是局部變量榆骚,那么就是值傳遞棠涮,外界改了臀稚,不會(huì)影響里面
如果block訪問的外部變量是__block或者static修飾崭闲,或者是全局變量肋联,那么就是指針傳遞,block里面的值和外界同一個(gè)變量刁俭,外界改變橄仍,內(nèi)部也改變;
Block內(nèi)存管理
(1)無論當(dāng)前環(huán)境是ARC 還是 MRC牍戚,只要block沒有訪問外部變量侮繁,block始終在全局區(qū);
(2)MRC情況下:
1.block如果訪問外部變量如孝,block在棧里
2.不能對(duì)block使用retain宪哩,否則不能保存在堆里
3.只有使用copy,才能放到堆里
ARC情況下:
1.block如果訪問外部變量第晰,block在堆里
2.block可以使用copy和strong锁孟,并且block是一個(gè)對(duì)象
Block注意事項(xiàng)
(1)Block可以訪問外部變量(局部變量不能修改)但是可以改變?nèi)肿兞俊㈧o態(tài)變量茁瘦、全局靜態(tài)變量品抽;
(2)如果需要在block內(nèi)部修改局部變量的值,使用__block修飾符外部變量甜熔;
(3)在block內(nèi)部使用外部指針會(huì)造成循環(huán)引用圆恤,需要使用__weak修飾外部指針
__weak typeof(self) weakSelf = self;
使用__weak,也會(huì)有一個(gè)隱患腔稀,在block內(nèi)部如果調(diào)用了延時(shí)函數(shù)還使用弱指針會(huì)娶不到該指針盆昙,因?yàn)橐呀?jīng)被銷毀了,為了保證在block內(nèi)不會(huì)被釋放焊虏,我們添加__strong淡喜。更多的時(shí)候需要配合strongSelf使用:
__weak typeof(self) weakSelf = self;
self.testBlock = ^{
__strong __typeof(weakSelf) strongSelf = weakSelf;
[strongSelf test];
});
Block傳值
有兩個(gè)視圖控制器 A 和 B,現(xiàn)在點(diǎn)擊 A 上的按鈕跳轉(zhuǎn)到視圖 B 诵闭,并在 B 中的textfield 輸入字符串拆火,點(diǎn)擊 B 中的跳轉(zhuǎn)按鈕跳轉(zhuǎn)回 A ,并將之前輸入的字符串顯示在 A 中的 label 上涂圆。也就是說 A 視圖中需要回調(diào) B 視圖中的數(shù)據(jù)们镜。
BViewController.h代碼:
typedef void(^CallBackBlcok) (NSString *text);
@interface BViewController : UIViewController
@property (nonatomic,copy)CallBackBlcok callBackBlock;
@end
BViewController.m代碼:
- (IBAction)click:(id)sender {
self.callBackBlock(_textField.text);
[self.navigationController popToRootViewControllerAnimated:YES];
}
AViewController.m代碼:
- (IBAction)push:(id)sender {
BViewController *bVC = [BViewController alloc]init];
__weak AViewController *weakSelf = self;
bVC.callBackBlock = ^(NSString *text){
NSLog(@"text is %@",text);
weakSelf.label.text = text;
};
[self.navigationController pushViewController:bVC animated:YES];
}