复制属性和Block_copy(myBlock)/ [myBlock copy]

ver*_*rec 7 block objective-c ios automatic-ref-counting

考虑:

typedef void (^select_block_t)(UIView *) ;

(1) @property (copy, nonatomic) select_block_t        myBlockProperty ;
(2) @property (strong, nonatomic) select_block_t      myBlockProperty ;
(3) @property (assign, nonatomic) select_block_t      myBlockProperty ;
Run Code Online (Sandbox Code Playgroud)

和:

(A) self.myBlockProperty = ^(UIView *) {NSLog(@"Hi");} ;
(B) self.myBlockProperty = [^(UIView *) {NSLog(@"Hi");} copy] ;
Run Code Online (Sandbox Code Playgroud)

我试图了解映射哪个属性声明与块复制语义的正确方法是什么

我看到的例子在这里SO这将有利于[1:B]

但后来我对"复制"操作多么冗余感到困惑.我有限的理解是[1:A]应该是正确的,因为我希望在分配属性时复制块一次,而不是在创建块时再复制一次,然后在属性赋值时再次复制.

根据我的理由,[3:B]也有意义.那么,我有什么误解?

joe*_*ick 9

[1:A]是对的,是的.[3:B]不正确,因为:

  1. 不清楚该类是否拥有该属性,因此应该以dealloc(但它应该)释放它
  2. setter(B)看起来像是一个泄漏,静态分析器可能会标记它,因为块被复制,传递给属性,然后保留带有保留计数+1的范围.
  3. using(3)表示只有在设置保留计数为1的堆块(复制块)时它才有效.使用该属性时,这会留下足够的误差.(1)适用于堆栈块和堆块,并且还将正确保留自动释放的块.

编辑:我看到你正在使用ARC.在这种情况下,根本不可能使用[3:B].copy一旦对象超出范围,编译器将释放一个对象(即使在编辑时),并且此属性设置器将不会保留它.因此该属性将包含一个错误的指针,它是一个等待发生的EXC_BAD_ACCESS.