mAu*_*mAu 6 block objective-c ios
一个小问题:为什么Xcode抱怨listing 1会导致保留周期,而listing 2不是?在这两种情况下_clients都是一个int实例变量.在listing 2它被分配0的init方法.
背景信息:我想在块中执行循环,只要至少有一个客户端从iPhone加速度计请求更新,我将发布到redis频道.如果没有剩余客户端,则循环将退出并停止发布加速计数据.
Listing 2来自我写的一个小测试应用程序来验证我的想法是否有效.Listing 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;
}
Run Code Online (Sandbox Code Playgroud)
- (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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
在两个列表中,您指的是一个实例变量,因此隐式捕获自身.一个强大的自我.
这导致您的问题的第一个解决方案:
int clients = _clients;
// use `clients` instead of `_clients` in your blocks
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用弱自我:
id __weak weakself = self;
// use `weakself->_clients` in your blocks
Run Code Online (Sandbox Code Playgroud)
你在列表1中得到错误的原因是因为块捕获self并且块存储在同一self的实例变量中,从而导致保留周期.上述两种解决方案都将解决该问题.
清单1中有一个保留周期,因为在清单1中,self保留了ivar _callback,您可以在其中访问其他ivar,_clients,并且因为_clients是原始的var,所以块保留自己访问它!
在清单2中,块由队列保留,而不是由self保留.
| 归档时间: |
|
| 查看次数: |
1185 次 |
| 最近记录: |