【问题标题】:Objective-C, ARC: Is it correct to use __weak arguments?Objective-C,ARC:使用 __weak 参数是否正确?
【发布时间】:2013-08-19 14:51:03
【问题描述】:

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

@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,您将获得一个保留周期,这是绝对正确的。

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

【问题讨论】:

  • 弱参考意味着没有保留,所以我认为这是正确的行为
  • 是的,您是对的,但我无法确定具体规范。
  • 我的意思是关于参数的规范,而不是 ivars、属性等。
  • @Rob:据我所知,即使使用 ARC,在某些情况下您也必须复制一个块。

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


【解决方案1】:

两个观察结果:

  1. 我倾向于在 doSomethingWithObject 中创建本地 __weak 引用,而不是像 Avoid Strong Reference Cycles when Capturing self 中所示将其作为 __weak 参数。

    我不认为正如您所问的那样,“使用弱论点是完全不安全的”。但如果不出意外,更常见的模式是拥有一个本地 __weak 变量,并且让我觉得它更适合作为 doSomethingWithObject 的实现细节,而不是方法的公共接口的一部分。

  2. 我还将使用 copy 内存限定符创建 block 属性。作为the docs say

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

因此:

@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

【讨论】:

  • 谢谢,@Rob!我知道替代解决方案,但我的问题来自“如果?”的类别。问题=)
  • @i_am_mushroom 明白了。答案是你可以,但你可能不应该。技术上没问题,但在我看来风格不是很好(因此我建议首选模式)。
  • 你知道,我问了一些同事关于 subj 的问题,他们很害怕 =) ...所以即使它是一种经过验证的技术,它也可能不好。无论如何,我也将问题发送到Clang Front End Users List
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多