OC基礎-Block

函數的一個重要做用:先把某一個代碼存起來,你想用的時候調函數就能用了
可是函數有個缺點,它不能動態定義,不能執行完一行忽然定義一個函數。函數的代碼
是死的,必定得在編譯以前把函數寫好,以前寫的函數是什麼,之後就是什麼。
這個時候,block就出現了。
void (^block)() = ^{
//裏面放的是代碼
};
大括號表明代碼塊。^號意味着代碼塊用block存儲。函數


void (^block)() 跟 函數 void play () 很像,
只是函數的名稱play換成了block的名稱(^block)指針

對比函數,block有一個好處,比較靈活,能夠在外面定義(這時是全局變量),也可
以在裏面定義(這時是局部變量),而函數只能在外面定義。對象

block跟函數同樣,有返回值,有參數。
沒有參數的block
//等號右邊沒有括號是由於沒有參數,不須要寫。
void (^block)() = ^{
//代碼
}blog

block先把大括號裏的代碼塊存起來,想執行裏面的代碼的時候,本身來調用。
問:如何調用沒有參數的block?
答:block(); 內存

有參數的block
int (^sumBlock)(int.int) = ^(int a,int b){
return a + b;
}
問:如何調用有參數的block?
答:int r = sumBlock(10,2); 編譯


格式:
返回值(^Block變量名)(參數類型) = ^(參數類型+形式參數){
//代碼
}變量

給Block起別名
錯誤寫法:typedef int (^sumBlock)(int.int) MyBlock;
正確寫法:typedef int (^MyBlock)(int.int);循環

問:如何定義起別名以後的block?
//用MyBlock類型來定義sumBlock變量,來保存下面這些代碼。
答:MyBlock sumBlock = ^(int a,int b){
return a + b;
}引用

MyBlock minusBlock = ^(int a,int b){
return a - b;
}
PS:MyBlock爲Block的類型,sumBlock和minusBlock爲Block的變量名(用變量名
來保存代碼)
那sumBlock和minusBlock是什麼類型呢?
是返回值爲int,有2個int類型參數的MyBlock類型。方法

 

 

block有一個特色,block裏面若是用了外部的一些變量什麼的(好比self),它會對這
個self產生一個強引用。也就是說,block會對控制器產生強引用。這樣會造成內存泄露
。意味着有些對象你根本不可能釋放。(緣由在於引起了循環引用)
PS:_age和self.age同樣,都會致使循環引用 _age等價於self->_age

解決方法:將block指向控制器的箭頭改成弱指針。

第一種作法:
__unsafe_unretained MJShareViewController *selfVc = self;
而後將方法內這句代碼以後的self所有改成selfVc便可。

第二種方法:
__weak MJShareViewController *selfVc = self;
__weak typeof(self) selfVc = self; //這樣寫更好,沒必要管控制器是什麼類型。
注意:typeof(self)等價於MJShareViewController * 都是控制器的類型。
而後將方法內這句代碼以後的self所有改成selfVc便可。

PS: __weak功能更多。能夠防止野指針,一旦發現野指針,會自動變成空指針。

相關文章
相關標籤/搜索