天天看點

Block Objects 學習筆記

Block Objects 學習筆記

Block 對象集合了面向對象程式設計和面向過程程式設計的特點。可以把Block是一種類型,可以擁有執行個體對象,可以用某個指針變量指向一個BLOCK對象。指向Block類型的對象的變量有變量名和類型。如下代碼:

NSString * string;

其中NSString *是類型,string是變量名。隻是聲明的文法稍有不同,如下代碼:

int (^ adder)(int a, int b);

adder是Block的變量名,其中符号^代表該變量是Block類型變量。前面的int表示該對象(adder)的傳回類型是int,後面的(int a,int b)表示該對想帶有兩個int類型的參數。

如下代碼:

   ^int(int x, int y){

       return x + y;

   };

隻是建立了一個Block,傳回值是int類型。通常情況下,應該将建立的block立刻賦給某個Block的變量,如下:

    int (^adder)(int, int) = ^int(int x, int y){

       return x + y;

   };

執行Block對象時,可以像c調用函數那樣調用Block變量,代碼如下:

   int (^adder)(int, int) = ^int(int x, int y){

       return x + y;

   };

   int sum = adder(2, 5);

NSLog(@"%i",sum);

輸出結果7

Block有一個很好的特性:它能捕獲變量。

首先了解Block對象的封閉作用域:對聲明了某個Block的對象方法,該方法的作用域就是這個Block的對象的封閉作用域。是以該Block可以通路該方法的所有局部變量、傳入該方法的實參以及傳入目前對象的執行個體變量。

如下代碼:

@interface Test1: NSObject

@property (nonatomic, copy) int (^testBlock)(int, int);

- (void) setTestBlock: (int (^)(int, int))block;

- (int) computeWithValue:(int)value addValue:(int)value2;

@end

#import "Test1.h"

@implementation Test1

@synthesize testBlock;

- (int) computeWithValue:(int)valueaddValue:(int)value2

{

   if (testBlock == nil)

    {

       return 0;

    }

   return testBlock(value, value2);

}

@end

    Test1 * example = [[Test1 alloc] init];

int a = 3;

[examplesetTestBlock:^int(int x, int y){

       int sum;

       sum = x + y;

       return sum * a;

}];

NSLog(@"%d",[example computeWithValue:8 addValue:4]);

輸出為36

當某個Block通路了一個在該Block之前聲明的變量時,就可以說該Block捕獲了這個變量。

“捕獲變量”的要點:一旦某個Block對象捕獲了某個變量的值,那麼無論執行該Block對象多少次,被捕獲的值也不會發生改變。并且被捕獲的變量的值在Block之後修改,Block捕獲的變量的值還是之前的值。代碼如下:

   int a = 3;

   [example setTestBlock:^int(int x, int y){

       int sum;

       sum = x + y;

       return sum * a;

   }];

    a= 6;

NSLog(@"%d",[example computeWithValue:8 addValue:4]);  

輸出值為36

這兒簡單總結關于 Block Objects 變量的特點:

1.    局部變量在 Block Objects 和 Objective-C 方法中的工作原理非常相似。

2.    對于内聯Block Objects,局部變臉不僅包含Block内部定義的變量,并且包含在BlockObjects執行方法中定義的變量。


3.    你不能參考self;在Objective-C類中運作的獨立Block Objects,如果你需要通路self,就必須把Object作為參數傳遞到 BlockObject

4.    隻有當 self 出現在建立 Block Object 的詞法範圍内,你可以在内聯 Block Object 内參考 self。

5.    對于内聯Block Objects,那些在BlockObject執行過程中定義的局部變量是可讀寫的,換句話說,對于Block Objects 自身的局部變量來說,Block Objects 有個讀寫存取。

6.    對于内聯 Block Objects,實作 Object 的 Objective-C 方法的局部變量隻能從中讀取,不能寫入。不過還有一個例外,如果定義它們通過 __block 存儲類型定義的話,Block Object可以寫入此類的變量。對此我們也會有舉例。

7.    假設你有一個類NSObject的Object,并且在這個Object的執行中你使用了一個Block Object與GCD相連,那麼在這個 Block Object 内部,你會有一個存儲來讀取那個支援你的 Block 執行的 NSObject内部的聲明屬性。