標籤:style ar color os 使用 sp for on div
1. block基礎 block聲明有點像c語言的函數指標
C代碼
- int func(int);
-
- int (*pfunc)(int);
-
- int func(int p)
- {
- printf("%d", p);
- return p;
- }
其中func是函數, pfunc是函數指標
函數指標賦值 pfunc = &func;
函數指標使用 (*pfunc)(100);
block的聲明 int (^bfunc)(int);
block的賦值 bfunc = ^(int p){ printf("%d", p); return p; };
block的使用 bfunc(10);
有些情況下,使用者需要在多個地方用到簽名相同的block,那麼可以用typedef來定義block類型, 如
C代碼
- typedef int (^MyBlock)(int);
- MyBlock block1 = ^(int p){
- printf("%d", p);
- return p;
- }
-
- MyBlock block2 = ^(int p){
- printf("%d", p * 2);
- return p * 2;
- }
2. block對外部變數的使用 對於全域變數,靜態變數,類成員變數處理方式是相同的,但對於局部變數,在定義完block之後,它的值就被固定了,即使在block本身被調用之前修改了,在block內部使用的局部變數依然是block被定義時的值
以下是範例程式碼,其中var1是全域變數, var2是全域靜態變數, var3是類的成員變數, var4是函數的局部變數。
C代碼
- typedef void (^MyBlock)(int);
- ….
-
-
- var1 = 1;
- MyBlock block1 = ^(int p)
- {
- printf("\nvar1:%d", var1);
- };
-
- block1(0);
- var1 = 2;
- block1(0);
-
- var2 = 2;
- MyBlock block2 = ^(int p)
- {
- printf("\nvar2:%d", var2);
- };
-
-
- block2(0);
- var2 = 3;
- block2(0);
-
- var3 = 3;
- MyBlock block3 = ^(int p)
- {
- printf("\nvar3:%d", var3);
- };
-
- block3(0);
- var3 = 4;
- block3(0);
-
- var4 = 4;
- MyBlock block4 = ^(int p)
- {
- printf("\nvar4:%d", var4);
- };
-
-
- block4(0);
- var4 = 5;
- block4(0);
這段代碼執行的結果是: var1:1 var1:2 var2:2 var2:3 var3:3 var3:4 var4:4 var4:4
對於全域變數、靜態變數和類成員變數,block中的代碼是可以修改它們的值的。 但對於局部變數,預設情況下block把它當作常量處理,如果需要修改,必須在局部變數定義的地方加上修飾符 __block
3. block和Objective-C物件變數
對於全域變數和靜態變數,相比普通變數沒有任何特殊的地方。 根據apple的官方文檔,對於成員變數和局部變數,在block中引用會引起retainCount的變化。對成員變數的直接引用會使成員變數所在的那個對象retainCount + 1, 對局部變數的引用會使局部變數的retainCount + 1。如果對局部變數使用__block作為修飾符,就可以使局部變數被block引用時不進行retain的操作。
我自己嘗試了一下,發現有一點apple的文檔裡沒有寫清楚,block對成員變數和局部變數引用時並不一定會引起retainCount的變化,以下是我的測試代碼。
obj3是成員變數
C代碼
- obj3 = [[TestObjectalloc] init];
- printf("\nself retain count:%d", [selfretainCount]);
- MyBlock block6 = ^(int p)
- {
- printf("\nself retain count:%d", [selfretainCount]);
- printf("\nobj retain count:%d", [obj3retainCount]);
- };
- block6(0);
- printf("\nself retain count:%d", [selfretainCount]);
輸出結果: self retain count:1 self retain count:1 obj retain count:1 self retain count:1
C代碼
- obj3 = [[TestObjectalloc] init];
- printf("\nself retain count:%d", [selfretainCount]);
- MyBlock block7 = ^(int p)
- {
- printf("\nself retain count:%d", [selfretainCount]);
- printf("\nobj retain count:%d", [obj3retainCount]);
- };
- MyBlock block77 = Block_copy(block7);
- block7(0); //或者 block77(0);
- printf("\nself retain count:%d", [selfretainCount]);
- Block_release(block77);
- printf("\nself retain count:%d", [selfretainCount]);
self retain count:1 self retain count:2 obj retain count:1 self retain count:2 self retain count:1
obj4是局部變數
C代碼
- TestObject *obj4 = [[TestObjectalloc] initWithValue:4];
- MyBlock block8 = ^(int p)
- {
- printf("\nobj4 retain count:%d", [obj4 retainCount]);
- };
- MyBlock block88 = Block_copy(block8);
- block88(0);
- printf("\nobj4 retain count:%d", [obj4 retainCount]);
- Block_release(block88);
- printf("\nobj4 retain count:%d", [obj4 retainCount]);
obj4 retain count:2 obj4 retain count:2 obj4 retain count:1
C代碼
- __block TestObject *obj5 = [[TestObjectalloc] initWithValue:5];
- MyBlock block9 = ^(int p)
- {
- printf("\nobj5 retain count:%d", [obj5 retainCount]);
- };
- MyBlock block99 = Block_copy(block9);
- block99(0);
- printf("\nobj5 retain count:%d", [obj5 retainCount]);
- Block_release(block99);
- printf("\nobj5 retain count:%d", [obj5 retainCount]);
obj5 retain count:1 obj5 retain count:1 obj5 retain count:1
結論是在一個方法內的block對對象的引用不會引起retainCount變化,但是調用Block_copy以後,retainCount會變化,但是block執行完以後引用對象的retainCount不會增加,需要調用Block_release才能釋放之前Block_copy引起的retainCount增加。
objective c 代碼塊blocks完整總結二