简体   繁体   中英

Can __weak self turn nil in the middle of the block?

When using a __weak self reference in my block that runs on a background thread, do I only need to check for nil in the beginning, or can the __weak self become nil even during execution after the first nil test has passed? I want to access some ivars from self in the block and I need the latest values at the time the block is executing.

If no one is holding a reference to self then yes. You can mitigate this by taking a strong reference in the block

__weak __typeof(self) weakSelf = self;

^{
  __strong __typeof(weakSelf) strongSelf = weakSelf;
  if (!strongSelf) {
    return;
  }
};

You can avoid having your reference set to nil by strongly referencing it from inside the block.

Get a strong reference to your weak pointer inside the block.

__weak MyObject *weakSelf = self; // a weak reference
myBlock = ^{
  MyObject *innerSelf = weakSelf; // a block-local strong reference
  NSLog(@"MyObject: %@", innerSelf); 
};

Avoid using the variables directly, because it will cause retain cycles. If you use an instance variable directly within a block, the block will capture self so you'll have to reference the instance variables using their accessors.

__weak MyObject *weakSelf = self;
myBlock = ^{
    MyObject *innerSelf = weakSelf; // a block-local strong reference
    NSLog(@"MyObject: %@", innerSelf);
    NSLog(@"MyObject ID: %d", innerSelf.objectID);
};

If you use the instance variables directly like this:

NSLog(@"MyObject ID: %d", _objectID);

The compiler interprets _objectID as self->_objectID , where self is captured by your block.

It is in the nature of a weak reference that it can become nil at any time, when the last strong reference is removed in another thread. This is fatal if you access member variables because you will crash, and it is fatal if you call a method on that weak variable, since self is unsafe unretained.

There is a trivial way to fix this which everyone uses: Store the weak variable into a string one before doing anything, without any checks. Then you check whether the strong variable is nil; that check is needed once .

Turn all warnings on in Xcode, so you will get a warning if you do anything dangerous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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