block的定義:「帶自動變量的匿名函數」函數
(一)寫法: spa
^ void (int iAge){ NSLog(@"%d", iAge);};
和C函數寫法區別在於:翻譯
1) :以插入符號 ^ 開始.code
2):沒有函數名字blog
當block聲明變量時候的寫法內存
void (^blk)(int iAge)
block 作函數參數時候 it
void testFunction:(int)age complete:(void(^)(int iAge))complete{ age++; if(complete){ complete(age); } }
(二)block是c語音的擴展,實際上block會被翻譯成c語言的static 結構體和static方法,這就是爲何block能截獲自動變量的緣由。io
-(id)init{ if (self = [super init]) { int iTmp = 0; ^(int i){ iTmp = 10; }; } return self; } 修改變量編譯報錯 修改成 -(id)init{ if (self = [super init]) { __block int iTmp = 0; ^(int i){ iTmp = 10; }; } return self; }
(三)關於block循環引用致使內存泄漏編譯
1):block中使用到類的strong類型變量以及使用到self ,會致使內存泄露。通常解決辦法class
a:開啓ARC 使用__weak 臨時變量作轉存。
@interface MyTest:NSObject{ strong id param; }
- (id)init{ if(self = [super init]){ ^(){ NSLog(@"%@", self); NSLog(@"%@", param);//XCode也會報告警告的,提示有循環引用 } } } //修改以下 - (id)init{ if(self = [super init]){ __weak id tmp = param; __weak id selfTmp = self; ^(){ NSLog(@"%@", selfTmp); NSLog(@"%@",tmp);//XCode也會報告警告的,提示有循環引用 } } }
b:若ARC關閉了,可以使用__block類型臨時變量,再在block中把臨時變量賦值爲nil,只是必須調用該block,否則同樣會內存泄漏
- (id)init{ if(self = [super init]){ __block id tmp = param; void (^blk)() = ^(){ NSLog(@"%@",tmp); tmp = nil; } } }
循環引用的緣由在於有strong 修飾的自動變量會被複制到堆上,copy.
在關閉ARC,須要手動 Block_copy() block 和Block_relase()