Objective-C,ARC:使用__weak参数是否正确?

时间:2013-08-19 14:51:03

标签: objective-c arguments automatic-ref-counting weak-references

这是使用弱参数的一个小例子:

@interface MYTestObject : NSObject

@end

@implementation MYTestObject {
   void(^_block)(void);
}

- (void)dealloc {
   NSLog(@"DEALLOC!");
}

- (id)init {
   if (self = [super init]) {
      [self doSomethingWithObject:self];
   }
   return self;
}

- (void)doSomethingWithObject:(id __weak /* <- weak argument! */)obj {
   _block = ^{
      NSLog(@"%p", obj);
   };
}

@end

它有效:-dealloc被召唤! 此外,如果您删除__weak,您将获得保留周期,这绝对是正确的。

不知道,如果这只是一个副作用,那么使用弱参数是完全不安全的吗?或者它是一个特定的行为,我只是一个糟糕的谷歌用户?

1 个答案:

答案 0 :(得分:5)

两个观察结果:

  1. 我倾向于在__weak中制作本地doSomethingWithObject引用,而不是Avoid Strong Reference Cycles when Capturing self中所示的__weak参数。

    我不认为,正如你所说的那样,“使用弱论点完全不安全”。但是如果没有其他的话,那么拥有本地__weak变量的更常见模式会让我觉得它更适合作为doSomethingWithObject的实现细节,而不是方法的公共接口的一部分。

    < / LI>
  2. 我还要使block内存限定符copy属性。作为the docs say

      

    您应指定copy作为属性属性,因为需要复制块以跟踪其在原始范围之外的捕获状态。这不是您在使用自动引用计数时需要担心的事情,因为它会自动发生,但是属性属性的最佳实践是显示结果行为。

  3. 因此:

    @interface MYTestObject : NSObject
    @property (nonatomic, copy) void(^block)(void);
    @end
    
    @implementation MYTestObject
    
    - (void)dealloc {
        NSLog(@"DEALLOC!");
    }
    
    - (id)init {
        if (self = [super init]) {
            [self doSomethingWithObject:self];
        }
        return self;
    }
    
    - (void)doSomethingWithObject:(MYTestObject *)obj { 
    
        typeof(obj) __weak weakObj = obj;
    
        self.block = ^{
            NSLog(@"%p", weakObj);
        };
    }
    
    @end