1. 建立block變數的並使用:
1 typedef int (^BLK)(int); // 定義block類型2 3 - (void)doSomething4 {5 BLK foo = ^(int a){ return a*a; }; // 建立block變數6 printf("%d", foo(4)); // 直接調用block7 }
2. 不建立block變數,直接建立內聯block,比如調用一個對數組進行排序的函數:
1 - (void)doSomething2 {3 NSArray *array = nil;4 [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {5 // do comparation6 return NSOrderedSame;7 }];8 }
3. block可以修改相同範圍內的變數,只要用__block來修飾某變數,在隨後範圍中調用的block可以改變其值。
4. 一個block就是一個匿名的內聯代碼集合體,和函數一樣有參數列表、傳回型別。
5. block可以捕獲它聲明所在範圍的狀態,可選地修改這些狀態。相同範圍內聲明的block共用這些狀態。
6. 同一範圍中聲明的block,在棧幀被銷毀後持續共用和更改此範圍中的狀態。
7. 儘管block在純C和C++上面可用,但一個block也同樣是一個Objective-C的對象。
8. 使用block代替傳統回呼函數可以使你在調用的地方編寫回呼函數要執行的操作,由於block可以直接存取局部變數,省去了給回呼函數傳一堆上下文資訊的麻煩。
9. block還支援可變參數。一個沒有使用任何參數的block必須在參數列表上面用void標明。
10. block中可以訪問全域變數、全域靜態變數、局部靜態變數、局部變數、參數。
11. __block變數不能是可變長的數組,也不能是包含可變長數組的資料結構。
12. __block變數不會被retain。
13. 通常不需要拷貝block,當需要block在被聲明的範圍銷毀後能繼續使用的話,就需要拷貝到堆上去。
14. 當拷貝一個block時,任何在該block中對其它block的引用都會在需要的時候被拷貝。
15. 拷貝一個棧上block時,會得到一個新的block;拷貝一個堆上block時,只是增加了該block的引用計數。
16. block被拷貝的時候會對其引用的對象進行retain操作。引用self、引用成員對象或調用成員函數會對self進行retain操作,成員對象無影響。這裡關鍵是被拷貝的時候,如果block沒有被拷貝則無此。
17. 引用成員變數會對self進行retain,而如果在聲明block之前聲明一個局部的變數,將成員變數賦值給這個局部變數,再在block中訪問這個局部變數則不會對self進行retain,但是局部變數的值不會跟成員變數的值一起變化,局部變數的值固定為建立時候的值,即當後來如果改變成員變數的值,再調用block,也不會用到新的值。