iOS block的一些自我見解

Auditore發表於2017-12-29

看了網上各類關於block的文章,受益匪淺,正好自己也總結下。

認知事物,一般分為三個步驟,是什麼?為什麼?怎麼用?

###1.什麼是block?

block是iOS4.0+ 和Mac OSX 10.6+ 引進的對C語言的擴充套件,用來實現匿名函式的特性。 block的結構如下圖:

block結構
在OC裡面,我們可以用快捷縮寫 inlineblock快速敲出block,

<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {

<#statements#>

};
複製程式碼

等式左邊分別為返回值型別、block名稱、引數型別, 右邊為引數型別和引數的名稱,以及block返回體.

###2.為什麼要用block?

block簡潔,易用,提高程式碼利用率。block可以作為頁面間跳轉時的傳值,也可用於複用程式碼片段

###3.怎麼用block

三種用法如下

####1)無返回值無引數

- (void)myHahaBlock

{

  //1.定義block

        void(^myHahaBlock)() = ^{

            NSLog(@"無參無返");

      };

//2.呼叫block

myHahaBlock();

}
複製程式碼

輸出結果:

2016-08-20 09:56:50.124 hahablock[750:25107] 無參無返

####2)有引數沒有返回值

- (void)myLolBlock

{

//1.定義block

           void(^myLolBlock)(int,int) = ^ (int num1,int num2){

                NSLog(@"有參無返:%d",num1 + num2);

            };

//2.呼叫block

myLolBlock(3,3);

}
複製程式碼

輸出結果:

2016-08-20 11:03:22.221 hahablock[811:30160] 有參無返:6

####3)有引數有返回值

- (void)myHohoBlock

{

        //1.定義block  

          double(^myHohoBlock)(double,double) = ^ (double r1,double r2){

                   return r1 + r2;

             };

//2.呼叫block

double r3 = myHohoBlock(1.2,2.2);

NSLog(@"有參有返:%f",r3);

}
複製程式碼

輸出結果:

2016-08-20 11:06:42.615 hahablock[861:32505] 有參有返:3.400000

####4.block作為引數傳遞

參考http://www.jianshu.com/p/d28a5633b963 講得很好 不贅述了

這裡順帶講一講代理傳值,引用下我在百度知道上的回答:

iOS delegate設計模式,在OC或者swift裡都是很常見的。比如最常用的tableview的delegate和datasource這兩個代理,實現之後就能使用它們的代理方法。

OK,有細想過為什麼嗎?為什麼我們在cellForRow實現的方法就能改變cell的內容了呢?

舉個例子,我每天都要打掃房間,但是呢,我比較懶,就想僱傭個人給我打掃房間,於是delegate就來了,某個年輕漂亮的MM應聘了這活兒。她把delegate設成了self,於是呢,就每天給我打掃房間(實現代理方法),最後得到的結果是我的房間乾淨了,她使用了我的代理方法。

代理方法的目的,就是為了傳值,把代理物件需要傳遞的值,放進代理方法裡,當執行到某個狀況的時候,我們把得到的值丟進我們的代理方法裡。一旦有人代理了我們,成了代理物件,她就能獲取到我們放到代理方法的值,也就完成了傳值。

程式碼塊也是一樣,也是在頁面跳轉間傳值,一般是逆向傳值,例如

A頁面跳轉到B頁面,如果想在B頁面回傳值給A。我們用代理就是在B宣告代理,寫好代理方法,找到要傳值的地方,把值扔進代理方法。A頁面實現B的代理方法,取出代理方法裡的形參也就完成了傳值。不覺得很麻煩嗎?又要宣告代理,又要設定代理物件。那麼程式碼塊呢?首先也是一樣,在B頁面宣告個程式碼塊,設成屬性。然後把需要傳遞的值扔進程式碼塊裡。記得判斷下程式碼塊是否存在。程式碼塊直接在A push 到B的時候,通過宣告B物件,可以取得它的屬性,也就是能獲取到B內的程式碼塊,然後也就能獲取到B內的值,也就完成了傳值。

很相似對不對?我看過一段很精闢的話如下:

那麼在類中定義一個Block,特別是在-viewDidLoad方法體內定義一個Block到底有什麼意義呢?我表示這時候只把它當做私有函式就可以了。我之前說過,Block其實就相當於代理,那麼這時候我該怎樣將其與代理類比以瞭解呢。這時候我可以這樣說:本類中的Block就相當於類自己服從某個協議,然後讓自己代理自己去做某個事情。

豁然開朗!這麼理解程式碼塊,就瞬間明白了,興奮不已。透過現象看本質,抽象事務,這才是需要學習和提高的地方。

下篇,我打算講講block記憶體洩露,下期見!

相關文章