Is it necessary to use weak references to self always inside blocks..?

前端 未结 2 513
独厮守ぢ
独厮守ぢ 2020-12-12 13:15

I am getting confused with use of self inside blocks, I go through some of Apple\'s documents but still cannot find the right answer.

Some people always say use weak

2条回答
  •  粉色の甜心
    2020-12-12 13:45

    Here's some code that demonstrates @WDUK's answer:

    typedef void (^SimpleBlock)();
    
    @interface ObjectThatRetainsBlock : NSObject
    @property(nonatomic, strong) SimpleBlock block;
    @end
    
    @implementation ObjectThatRetainsBlock
    
    - (instancetype)init {
      self = [super init];
      if (self) {
        self.block = ^{ NSLog(@"Running block in %@", self); };
        self.block();
      }
      return self;
    }
    
    - (void)dealloc {
      NSLog(@"ObjectThatRetainsBlock is deallocated.");
    }
    
    @end
    
    @interface ObjectThatDoesNotRetainBlock : NSObject
    @end
    
    @implementation ObjectThatDoesNotRetainBlock
    
    - (instancetype)init {
      self = [super init];
      if (self) {
        SimpleBlock block = ^{ NSLog(@"Running block in %@", self); };
        block();
      }
      return self;
    }
    
    - (void)dealloc {
      NSLog(@"ObjectThatDoesNotRetainBlock is deallocated.");
    }
    
    @end
    
    - (void)test {
      ObjectThatRetainsBlock *objectThatRetainsBlock =
          [[ObjectThatRetainsBlock alloc] init];
      ObjectThatDoesNotRetainBlock *objectThatDoesNotRetainBlock = 
          [[ObjectThatDoesNotRetainBlock alloc] init];
    }
    

    The test method prints:

    Running block in 
    Running block in 
    ObjectThatDoesNotRetainBlock is deallocated.
    

    Observe that in the init method of ObjectThatDoesNotRetainBlock, we create block as an ivar, but when the block goes out of scope, we don't keep a reference to it.

    In the test method, when the two objects go out of scope, observe that objectThatDoesNotRetainBlock is deallocated because it is not part of a retain cycle.

    On the other hand, objectThatRetainsBlock does not get deallocated, because it is part of a retain cycle. It retains the block beyond the scope of the method call.

    If you want an another explanation, see this answer.

提交回复
热议问题