阻止并保留周期 [英] Blocks and retain cycles

查看:116
本文介绍了阻止并保留周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个小问题:为什么Xcode抱怨列出1 会导致保留周期,而在列表2 它没有?在这两种情况下, _clients 都是 int 实例变量。在列表2 中,在 init 方法中为其分配 0

One minor question: why is Xcode complaining that listing 1 would lead to a retain cycle, while in listing 2 it does not? In both cases _clients is an int instance variable. In listing 2 it is assigned 0 in the init method.

背景信息:我想在块中执行循环,只要至少有一个客户端从iPhone加速度计请求更新,我将发布到一个redis频道。如果没有剩下的客户端,循环将退出并停止发布加速计数据。

Background info: I would like to execute the loop in the block, as long as at least one client is requesting updates from the iPhone accelerometer, which I am publishing to a redis channel. If there are no more clients left, the loop would quit and stop publishing accelerometer data.

清单2 来自我写的一个小测试应用程序,用于验证我的想法是否有效。 清单1 在实际项目中实现。

Listing 2 comes from a small test app I wrote to verify that my idea works. Listing 1 is implemented in the real project.

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



清单2



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


推荐答案

在这两个清单中,你是引用一个实例变量,从而隐含地捕获自我。一个强大的自我。

In both listings, you are referring to an instance variable, thus implicitly capturing self. A strong self.

这将为您的问题提供第一个解决方案:

This leads to a first solution to your problem:

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

或者,你可以使用弱自我:

Alternatively, you can use a weak self:

id __weak weakself = self;
// use `weakself->_clients` in your blocks

你之所以这样得到清单1中的错误是因为块捕获self并且块存储在同一self的实例变量中,从而导致保留周期。上述两种解决方案都可以解决这个问题。

The reason why you got the error in listing 1 is because the block captures self and the block is stored in an instance variable of the same self, leading to a retain cycle. Both solutions above will solve that issue.

这篇关于阻止并保留周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆