關於 block的一些淺識

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()

相關文章
相關標籤/搜索