Block recursion and breaking retain cycle

后端 未结 2 1862
清酒与你
清酒与你 2021-02-13 00:03

To better illustrate the question, consider the following simplified form of block recursion:

__block void (^next)(int) = ^(int index) {
    if (index == 3) {
           


        
2条回答
  •  暖寄归人
    2021-02-13 00:30

    I think @newacct is correct about @Matt Wilding's solution; it does seem that nothing will have a strong ref to the next block in that case and will result in a run time exception when run (at least it did for me).

    I don't know how common it is to find recursively called blocks in the wild in objc. However, in a real world implementation (if actually required) on say, a view controller, one might define the block and then set up an internal interface property with a strong reference to said block:

    typedef void(^PushButtonBlock)();
    
    @interface ViewController ()
    @property (strong, nonatomic) PushButtonBlock pushButton;
    @end
    
    @implementation ViewController
      ... 
      // (in viewDidLoad or some such)
      __weak ViewController *weakSelf = self;
    
      self.pushButton = ^() {
        [weakSelf.button pushIt];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), weakSelf.pushButton);
      };
    
      self.pushButton();
      ...
    @end
    

    This runs fine for me and has no compiler warnings about retain cycles (and no leaks in instruments). But, I think I would probably steer clear of doing this (recursive block calls) in most cases in objc - it's smelly. But interesting in any case.

提交回复
热议问题