简体   繁体   English

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

[英]Objective-C, ARC: Is it correct to use __weak arguments?

Here's a little example of using weak arguments: 这是一个使用弱参数的小例子:

@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

And it works: -dealloc is called! 它的工作原理是: -dealloc被调用! Also, if you remove __weak you'll get a retain-cycle and it's absolutely correct. 另外,如果删除__weak ,则会得到一个保留周期,这是绝对正确的。

Wonder, if that's just a side-effect and it's completely unsafe to use weak arguments? 不知道这是否只是副作用,并且使用弱参数完全不安全吗? Or is it a specified behavior and I'm just a bad google-user? 还是这是一种特定的行为,而我只是一个不好的Google用户?

Two observations: 两个观察:

  1. I'd be inclined to make a local __weak reference within doSomethingWithObject , rather than make it a __weak argument as illustrated in Avoid Strong Reference Cycles when Capturing self . 我倾向于在doSomethingWithObject内进行局部__weak引用,而不是像捕获self时避免强引用循环中所示将其作为__weak参数。

    I don't think that it is, as you asked, "completely unsafe to use weak arguments." 正如您所问的那样,我认为使用弱参数完全不安全。 But if nothing else, it's the more common pattern to have a local __weak variable and strikes me as more appropriate as an implementation detail of doSomethingWithObject rather than part of the method's public interface. 但是,如果没有其他问题,那是更常见的模式,它具有局部__weak变量,使我觉得更适合作为doSomethingWithObject的实现细节而不是方法的公共接口的一部分。

  2. I'd also make block a property with the copy memory qualifier. 我还将使用copy内存限定符使block一个属性。 As the docs say 正如文档所说

    You should specify copy as the property attribute, because a block needs to be copied to keep track of its captured state outside of the original scope. 您应该将copy指定为属性属性,因为需要复制一个块以跟踪其在原始范围之外的捕获状态。 This isn't something you need to worry about when using Automatic Reference Counting, as it will happen automatically, but it's best practice for the property attribute to show the resultant behavior. 使用自动引用计数时,您不必担心这件事,因为它会自动发生,但是,最好的做法是让property属性显示结果行为。

Thus: 从而:

@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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM