標籤:des style blog color 使用 os io strong
X.1 初探Block
在這一小節我們先用一些簡單範例來匯入block的概念。
X.1.1 宣告和使用Block
我們使用「^」運運算元來宣告一個block變數,而且在block的定義最後面要加上「;」來表示一個完整的述句(也就是將整個block定義視為前面章節所介紹的簡單述句,因為整個定義必須是一個完整的句子,所以必須在最後面加上分號),下面是一個block的範例:
1: int multiplier = 7 ;
2: int (^myBlock)( int ) = ^( int num)
3: {
4: return num * multiplier;
5: };
我們使用來解釋這個範例(請將文字框的字翻譯如下):
我們宣告一個「myBlock」變數,用「^」符號來表示這是一個block。
這是block的完整定義,這個定義將會指定給「myBlock」變數。
表示「myBlock」是一個回傳值為整數(int)的block。
它有一個參數,型態也是整數。
這個參數的名字叫做「num」。
這是block的內容。
值得注意的地方是block可以使用和本身定義範圍相同的變數,可以想像在上面的例子中 multiplier 和 myBlock 都是某一個函數內定義的兩個變數也就是這個變數都在某個函數兩個大括弧「{」和「 }」中間的區塊,因為它們的有效範圍是相同的,因此在block中就可以直接使用 multiplier 這個變數,此外當把block定義成一個變數的時,我們可以直接像使用一般函數般的方式使用它:
1: int multiplier = 7 ;
2: int (^myBlock)( int ) = ^( int num)
3: {
4: return num * multiplier;
5: };
6: printf ( "%d" , myBlock( 3 ));
7: //結果會列印出21
X.1.2 直接使用Block
在很多情況下,我們並不需要將block宣告成變數,反之我們可以直接在需要使用block的地方直接用內嵌的方式將block的內容寫出來,在下面的例子中qsort_b函數,這是一個類似傳統的qsort_t函數,但是直接使用block做為它的參數:
1: char *myCharacters[ 3 ] = { "TomJohn" , "George" , "Charles Condomine" };
2: qsort_b (myCharacters, 3 ,
3: sizeof ( char *),
4: ^( const void *l, const void *r)//block部分
5: {
6: char *left = *( char **)l;
7: char *right = *( char **)r;
8: return strncmp (left, right, 1 );
9: } //end
10: );
X.1.3 __block 變數
一般來說,在block內只能讀取在同一個範圍的變數而且沒有辦法修改在block外定義的任何變數,此時若我們想要這些變數能夠在block中被修改,就必須在前面掛上__block的修飾詞,以上面第一個例子中的 multiplier 來說,這個變數在 block 中是唯讀的,所以 multiplier = 7 指定完後,在 block 中的 multiplier 就只能是 7 不能修改,若我們在 block 中修改 multiplier ,在編輯時就會產生錯誤,因此若想要在 block 中修改 multiplier ,就必須在 multiplier 前面加上 __block 的修飾詞,請參考下面的範例:
1: __block int multiplier = 7 ;
2: int (^myBlock)( int ) = ^( int num)
3: {
4: if (num > 5 )
5: {
6: multiplier = 7 ;
7: }
8: else
9: {
10: multiplier = 10 ;
11: }
12: return num * multiplier;
13: };
使用block的範例程式碼
- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 200)]; view.backgroundColor = [UIColor yellowColor]; [self.view addSubview:view]; void (^blockAnimation)() = ^(){ view.frame = CGRectMake(100, 100, 100, 200); }; void (^blockFinished)(BOOL finished) = ^(BOOL finished){ view.frame = CGRectMake(0, 0, 100, 200); }; [UIView animateWithDuration:1.0 animations:blockAnimation completion:blockFinished]; }