1. 程式人生 > >初探iOS中的Block(程式碼塊與閉包)

初探iOS中的Block(程式碼塊與閉包)

支援原創,轉載請註明博主與博文連結,3Q吐舌頭

  —— by atany


一、Block是什麼?

       Block就是一個包含函式體的物件,有時候也被叫做閉包。

       概念可能還是有點模糊,沒關係,我們來看看用法得意

二、Block的宣告與建立。

程式碼塊的基本結構為:

returnType (^blockname)(list of arguments) =^(arguments){ body; }

舉個例子:我們定義一個作用為打出“Hello + 名字”的閉包。

void(^sayHelloBlock)(NSString*) = ^(NSString *personName){ 
	NSLog (@"Hello %@", personName);
};

對應的拆解:

void:返回值.

^sayHelloBlock[^]符號宣告block物件,“sayHelloBlock”為blockname

(NSString):block的輸入引數列表。(也可以寫成NSString *personName的完整形式)

(NSString *personName):詳細引數,必須寫完整形式,變數personName會在block中用到。

{ NSLog (@"Hello %@", personName);};body,也就是block的內容,這裡是打印出一句話。

宣告與建立完成後,我們來看看Block的使用:block的使用與函式十分相似,直接使用(block名稱+引數)的形式。

 sayHelloBlock(@"atany");

打印出:2013-09-1120:18:54.130 TestBlock[3137:c07] Hello atany

三、Block的特性

1)  Block可以訪問函式其他的內部變數

    NSString *person = @"Mary";

     void(^sayHelloBlock)()= ^{

        NSLog(@"Hello %@",person);

    };

    sayHelloBlock();

輸出:2013-09-11 20:26:06.050TestBlock[3176:c07] Hello Mary

可以看到person物件在Block的外部,但是Block卻能夠訪問到person物件的值Mary,這也是block最重要的一個特性。

2)  Block宣告時會捕捉建立點的狀態。

    NSString *person = @"Mary";

    void(^sayHelloBlock)()= ^{

        NSLog(@"Hello %@",person);

    };

    sayHelloBlock ();

    person = @"Peter";

    sayHelloBlock();


輸出:

2013-09-11 20:28:38.423 TestBlock[3200:c07] Hello Mary

2013-09-11 20:28:38.424TestBlock[3200:c07] Hello Mary

為什麼會這樣呢?怎麼沒有打出Hello Peter?

      原來當程式執行到Block的宣告時,Block會記錄建立點所用資源的狀態,此時person的值為“Mary”,Block儲存這個值的副本,再次使用時直接呼叫副本。所以即使在後面person的值變為了“Peter”,副本的值也不會改變。

那怎麼辦呢?有兩種解決方法。

1)  修改物件為靜態.

static NSString *person= @"Mary";

2)  在物件宣告前新增­__block.

 __block NSString *person = @"Mary";

輸出:

2013-09-11 20:35:29.838TestBlock[3244:c07] Hello Mary

2013-09-1120:35:29.840 TestBlock[3244:c07] Hello Peter

可以看到,兩個方法都可以解決問題。