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

情到浓时终转凉″ 提交于 2019-12-25 08:58:20

问题


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.


回答1:


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;
  }
};



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/29343394/can-weak-self-turn-nil-in-the-middle-of-the-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!