一个小问题:为什么Xcode提示listing 1会导致保留周期,而在listing 2中却没有呢?在这两种情况下,_clients都是int实例变量。在listing 2中,通过0方法为其分配了init

背景信息:只要至少一个客户端从我发布到Redis channel 的iPhone加速度计请求更新,我想在代码块中执行循环。如果没有更多的客户端,则循环将退出并停止发布加速度计数据。
Listing 2来自我编写的一个小型测试应用程序,目的是验证我的想法是否有效。 Listing 1在实际项目中实现。

list 1

- (id)init {
  self = [super init];

  if (self) {
    _clients = 0;

    /**
     * The callback being executed
     */
    _callback = ^ {
      while (_clients > 0) { // Capturing 'self' strongly in this block is likely to lead to a retain cycle
        NSLog(@"Publish accelerometer data to redis (connected clients: %d)", _clients);
      }
    };
  }

  return self;
}

list 2
- (void)touchedConnectButton:(id)sender {
  _clients += 1;

  dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  dispatch_async(concurrentQueue, ^() {
    while(_clients > 0) {
      NSLog(@"Connected clients: %d", _clients);
    }
  });
}

最佳答案

在这两个 list 中,您都引用了一个实例变量,从而隐式捕获了self。坚强的自我。

这将导致您的问题的第一个解决方案:

int clients = _clients;
// use `clients` instead of `_clients` in your blocks

另外,您可以使用弱自我:
id __weak weakself = self;
// use `weakself->_clients` in your blocks

list 1中出现错误的原因是因为该块捕获了self,并且该块存储在同一个self的实例变量中,从而导致了保留周期。以上两种解决方案都可以解决该问题。

关于objective-c - 阻止并保留周期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11428712/

10-09 16:15