阻止和保留周期

一个小问题:为什么Xcode抱怨listing 1会导致保留周期,而在listing 2却不会呢? 在这两种情况下, _clients都是一个int实例variables。 在listing 2它在init方法中被赋值为0

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

Listing 2来自我写的一个小testing应用程序,以validation我的想法是否有效。 Listing 1在实际项目中实现。

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

清单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); } }); } 

在这两个列表中,你指的是一个实例variables,从而隐式捕获自己。 强烈的自我。

这导致您的问题的第一个解决scheme:

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

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

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

清单1中出现错误的原因是,块捕获自己,块存储在同一个自己的实例variables中,导致保留周期。 上述两个解决scheme都将解决这个问题

清单1中有一个保留循环,因为在Listing1中,self保留了您访问另一个ivar _clients的ivar _callback,而_clients是一个基本的var,块保留了自己的访问权限!

在清单2中,该块由队列保留,而不是由自己保留。