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

时间:2012-04-09 16:39:50

标签: objective-c ios automatic-ref-counting block

考虑:

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 ;

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

我试图了解映射哪个属性声明与块复制语义

的正确方法是什么

我在[{3}}上看到了有利于[1:B]的示例here

但后来我对“复制”操作的多余程度感到困惑。 我有限的理解是[1:A]应该是正确的,因为我想要 我在分配属性时要复制一次的块,而不是在创建块时再复制一次,然后在属性赋值时再次复制。

根据我的理由,

[3:B]也是有道理的。那么,我误解了什么?

1 个答案:

答案 0 :(得分:9)

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

  1. 不清楚该类是否拥有该属性,因此应该以dealloc(但它应该)释放它
  2. setter(B)看起来像是一个泄漏,静态分析器可能会将其标记为这样,因为块被复制,传递给属性,然后保留范围保留计数+1。
  3. using(3)表示只有在设置保留计数为1的堆块(复制块)时才有效。使用该属性时,这会留下足够的误差。 (1)适用于堆栈块和堆块,并且还将正确保留自动释放的块。
  4. 编辑:我看到你正在使用ARC。在这种情况下,根本不可能使用[3:B]。一旦对象超出范围,编译器将释放一个对象(即使在copy时),并且此属性设置器将不会保留它。因此该属性将包含一个错误的指针,它是一个等待发生的EXC_BAD_ACCESS。