1. 程式人生 > >關於 block 會不會被自動 copy 的實驗和猜想

關於 block 會不會被自動 copy 的實驗和猜想

今天群裡不知怎麼說起了 block 在棧上還是在堆上的問題。好像之前在哪裡看到過,現在 block 的屬性已經不用寫 copy 關鍵字,就會自動 copy。於是做了幾個實驗,想看看什麼情況下會自動 copy,什麼情況下不會~

實驗

程式碼如下:

TestClass.h
12345678910111213 typedefvoid(^SimpleBlock)();@interfaceTestClass:NSObject@property(nonatomic,copy)SimpleBlock copyProperty;@property(nonatomic,strong)SimpleBlock strongProperty;@property(nonatomic,weak)SimpleBlock weakProperty;@property(nonatomic,assign)SimpleBlock
assignProperty;@end
main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 #import "TestClass.h"SimpleBlock someFunction(SimpleBlock block){NSLog(@"block as param : %@",block);returnblock;}intmain(intargc,constchar*argv[]){@autoreleasepool{__block inta=1;NSLog(@"orginal block : %@",^{a=2;});// as a variableSimpleBlock block=^{a=2;};NSLog(@"block as variable : %@",block);__weak SimpleBlock weakBlock=^{a=2;};NSLog(@"block as a weak variable : %@",weakBlock);// as propertiesTestClass*testClass=[TestClass new];testClass.weakProperty=^{a=2;};testClass.assignProperty=^{a=2;};testClass.copyProperty=^{a=2;};testClass.strongProperty=^{a=2;};NSLog(@"copy property : %@",testClass.copyProperty);NSLog(@"strong property : %@",testClass.strongProperty);NSLog(@"weak property : %@",testClass.weakProperty);NSLog(@"assign property : %@",testClass.assignProperty);NSLog(@"block as return value : %@",someFunction(^{a=2;}));}return0;}

實驗結果:

123456789 2017-02-0617:43:36.207212test2[27378:1079138]orginal block:2017-02-0617:43:36.207436test2[27378:1079138]block asvariable:2017-02-0617:43:36.207457test2[27378:1079138]block asaweak variable:2017-02-0617:43:36.207492test2[27378:1079138]copy property:2017-02-0617:43:36.207517test2[27378:1079138]strong property:2017-02-0617:43:36.207563test2[27378:1079138]weak property:2017-02-0617:43:36.207581test2[27378:1079138]assign property:2017-02-0617:43:36.207611test2[27378:1079138]block asparam:2017-02-0617:43:36.207769test2[27378:1079138]block asreturnvalue:

分析

  • 作為變數:
    • 一個 block 剛宣告的時候是在棧上
    • 賦值給一個普通變數之後就會被 copy 到堆上
    • 賦值給一個 weak 變數不會被 copy
  • 作為屬性:
    • 用 strong 和 copy 修飾的屬性會被 copy
    • 用 weak 和 assign 修飾的屬性不會被 copy
  • 函式傳參:
    • 作為引數傳入函式不會被 copy
    • 作為函式的返回值會被 copy

猜測

看著以上結論,感覺可以做出一個猜測:就是 block 被 retain 的時候就會自動被 copy,包括 autoRelease~ 這樣就能解釋為啥函式的引數不會被 copy,返回值就會被 copy。是不是很有道理呢 =w=

感謝諸位大神對本次實驗的支援~