objective c 代碼塊blocks完整總結二

來源:互聯網
上載者:User

標籤:style   ar   color   os   使用   sp   for   on   div   

1. block基礎 block聲明有點像c語言的函數指標

C代碼 
  1. int func(int);  
  2.   
  3. int (*pfunc)(int);  
  4.   
  5. int func(int p)  
  6. {  
  7.   printf("%d", p);  
  8.   return p;  
  9. }  

 

其中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代碼 
  1. typedef int (^MyBlock)(int);  
  2. MyBlock block1 = ^(int p){  
  3.   printf("%d", p);  
  4.   return p;  
  5. }  
  6.   
  7. MyBlock block2 = ^(int p){  
  8.   printf("%d", p * 2);  
  9.   return p * 2;  
  10. }  

 

2. block對外部變數的使用 對於全域變數,靜態變數,類成員變數處理方式是相同的,但對於局部變數,在定義完block之後,它的值就被固定了,即使在block本身被調用之前修改了,在block內部使用的局部變數依然是block被定義時的值
以下是範例程式碼,其中var1是全域變數, var2是全域靜態變數, var3是類的成員變數, var4是函數的局部變數。

C代碼 
  1. typedef void (^MyBlock)(int);  
  2. ….  
  3.   
  4.   
  5. var1 = 1;  
  6. MyBlock block1 = ^(int p)  
  7. {  
  8.     printf("\nvar1:%d", var1);  
  9. };  
  10.   
  11. block1(0);  
  12. var1 = 2;  
  13. block1(0);  
  14.      
  15. var2 = 2;  
  16. MyBlock block2 = ^(int p)  
  17. {  
  18.     printf("\nvar2:%d", var2);  
  19. };  
  20.   
  21.   
  22. block2(0);  
  23. var2 = 3;  
  24. block2(0);  
  25.      
  26. var3 = 3;  
  27. MyBlock block3 = ^(int p)  
  28. {  
  29.     printf("\nvar3:%d", var3);  
  30. };  
  31.      
  32. block3(0);  
  33. var3 = 4;  
  34. block3(0);  
  35.      
  36. var4 = 4;  
  37. MyBlock block4 = ^(int p)  
  38. {  
  39.     printf("\nvar4:%d", var4);  
  40. };  
  41.   
  42.   
  43. block4(0);  
  44. var4 = 5;  
  45. 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代碼 
  1. obj3 = [[TestObjectalloc] init];  
  2. printf("\nself retain count:%d", [selfretainCount]);  
  3. MyBlock block6 = ^(int p)  
  4. {  
  5.     printf("\nself retain count:%d", [selfretainCount]);  
  6.     printf("\nobj retain count:%d", [obj3retainCount]);  
  7. };  
  8. block6(0);  
  9. printf("\nself retain count:%d", [selfretainCount]);  

 

輸出結果: self retain count:1 self retain count:1 obj retain count:1 self retain count:1

C代碼 
  1. obj3 = [[TestObjectalloc] init];  
  2. printf("\nself retain count:%d", [selfretainCount]);  
  3. MyBlock block7 = ^(int p)  
  4. {  
  5.     printf("\nself retain count:%d", [selfretainCount]);  
  6.     printf("\nobj retain count:%d", [obj3retainCount]);  
  7. };  
  8. MyBlock block77 = Block_copy(block7);  
  9. block7(0); //或者 block77(0);  
  10. printf("\nself retain count:%d", [selfretainCount]);  
  11. Block_release(block77);  
  12. 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代碼 
  1. TestObject *obj4 = [[TestObjectalloc] initWithValue:4];  
  2. MyBlock block8 = ^(int p)  
  3. {  
  4.     printf("\nobj4 retain count:%d", [obj4 retainCount]);  
  5. };  
  6. MyBlock block88 = Block_copy(block8);  
  7. block88(0);  
  8. printf("\nobj4 retain count:%d", [obj4 retainCount]);  
  9. Block_release(block88);  
  10. printf("\nobj4 retain count:%d", [obj4 retainCount]);  

 

obj4 retain count:2 obj4 retain count:2 obj4 retain count:1

C代碼 
  1. __block TestObject *obj5 = [[TestObjectalloc] initWithValue:5];  
  2. MyBlock block9 = ^(int p)  
  3. {  
  4.     printf("\nobj5 retain count:%d", [obj5 retainCount]);  
  5. };  
  6. MyBlock block99 = Block_copy(block9);  
  7. block99(0);  
  8. printf("\nobj5 retain count:%d", [obj5 retainCount]);  
  9. Block_release(block99);  
  10. 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完整總結二

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.