-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dispatch_async的block里面需要__weak self 吗? #41
Comments
你可能需要再多了解一下 block、weak、strong 相关的内存管理。
在①处,block 会捕获到 _self,这个值是 weak 的,随后在 block 执行①时,这个 __weak _self 会被赋值为 __strong self。在②处,如果 weak self 已经被释放,那么这里就会直接返回。这么做能避免循环引用,并且能确保在使用 self 时其不会被释放。 如果你用过 ReactiveCocoa,或者写过一些常见的一些网络库的 block 回调,应该会对这种写法很熟悉。 |
|
self->_queue->block->self 这不是循环引用吗 |
如果self->_queue->block->self 是循环引用,那么self->_queue->block->strongSelf 难道就不是循环引用了么?所以这句话__strong typeof(_self) self = _self; 有什么意义呢? |
(void)_trimRecursively { 其次我觉得 if (!self) return 这个条件永远不会成立,因为这时候已经定了strongSelf强指针指向self对象,所以self的对象的引用计数必然已经+1了,直到block释放的时候才会-1,而此时显然blokc还没释放,所以self指向的对象的应用计数必然大于等于1,所以不会释放,所以!self条件必然不会成立。 |
官方文档上说会Block_copy() 和Block_release() ,所以会帮你打破引用循环,不用weak/strong应该也没问题 |
@Mryong ②那里有处理,所以没问题的 相当于 __weak typeof(self) weakSelf = self;
xxxxx ^ {
weakSelf.xxxxx
} |
GCD的应该不需要用 weakSelf。
_queue不会持有 block。 |
我认为使用weakSelf时,当这个viewController释放了,weakSelf会变成nil。 |
self在block释放时,不会释放,你先理解什么是强引用循环
邮箱:417497299@qq.com
签名由 网易邮箱大师 定制
在2018年04月02日 17:07,JohnDn 写道: 我认为使用weakSelf时,当这个viewController释放了,weakSelf会变成nil。
但是如果使用self,self会在Block释放时,才释放,应该不会造成循环引用。
—You are receiving this because you are subscribed to this thread.Reply to this email directly, view it on GitHub, or mute the thread.
{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ibireme/YYKit","title":"ibireme/YYKit","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/ibireme/YYKit"}},"updates":{"snippets":[{"icon":"PERSON","message":"@JohnDn in #41: 我认为使用weakSelf时,当这个viewController释放了,weakSelf会变成nil。\r\n但是如果使用self,self会在Block释放时,才释放,应该不会造成循环引用。\r\n"}],"action":{"name":"View Issue","url":"#41 (comment)"}}}
|
@tomschenjian 刚才可能没说清楚,我那段话里Block指的是dispatch_async block,这里只针对GCD中使用self进行讨论。当然一般情况里,self持有block,block中也强引用self,这样确实是强引用循环,block的释放需要依赖self的释放,同时self的释放也依赖block的释放。 但是在dispatch_async block回调中强引用了self,不会造成循环引用吧?dispatch_async block结束后会自动release,同时dispatch_async block对self的强引用也结束了,self也会释放。 还请大神多多指教。。。 |
这种情况block就没有强引用self,谈不上引用循环啊
邮箱:417497299@qq.com
签名由 网易邮箱大师 定制
在2018年04月02日 17:29,JohnDn 写道: @tomschenjian 刚才可能没说清楚,我那段话里Block指的是dispatch_async block,这里只针对GCD中使用self进行讨论。当然一般情况里,self持有block,block中也强引用self,这样确实是强引用循环,block的释放需要依赖self的释放,同时self的释放也依赖block的释放。
但是在dispatch_async block回调中强引用了self,不会造成循环引用吧?dispatch_async block结束后会自动release,同时dispatch_async block对self的强引用也结束了,self也会释放。
还请大神多多指教。。。
—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or mute the thread.
{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/ibireme/YYKit","title":"ibireme/YYKit","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/ibireme/YYKit"}},"updates":{"snippets":[{"icon":"PERSON","message":"@JohnDn in #41: @tomschenjian 刚才可能没说清楚,我那段话里Block指的是dispatch_async block,这里只针对GCD中使用self进行讨论。当然一般情况里,self持有block,block中也强引用self,这样确实是强引用循环,block的释放需要依赖self的释放,同时self的释放也依赖block的释放。\r\n\r\n但是在dispatch_async block回调中强引用了self,不会造成循环引用吧?dispatch_async block结束后会自动release,同时dispatch_async block对self的强引用也结束了,self也会释放。\r\n\r\n还请大神多多指教。。。"}],"action":{"name":"View Issue","url":"#41 (comment)"}}}
|
@Mryong 你没理解什么是循环引用,那里的 strongSelf 是在 {...} 代码块内部的临时变量!临时变量在代码块退出时会自动调用 release |
不用争了, self->queue -> async block -> weak self |
queue不会持有block,这样写也不会有循环引用
|
不是queue没有持有block,而且queue在执行完block后释放了block(赋值nil)🙂,它确实有循环引用,但是执行完后queue主动打破了循环引用。 |
|
这里是否有必要使用 |
有道理 |
有道理,但感觉作者没想这么多,可能单纯的只是写了下防循环引用而已,其实这里可以不用。看过很多人遇到block就weak的。 |
不一定的哈,需要分情况讨论 |
YYKit的代码: (YYDiskCache.m)
__weak typeof(self) _self = self;
dispatch_async(_queue, ^{
__strong typeof(_self) self = _self;
if (!self) return;
dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER);
[self _trimToCost:self.costLimit];
[self _trimToCount:self.countLimit];
[self _trimToAge:self.ageLimit];
[self _trimToFreeDiskSpace:self.freeDiskSpaceLimit];
dispatch_semaphore_signal(self->_lock);
});
}
看下dispatch_async官方文档说明:
block参数系统会自动调用copy,保证self不被释放,在block执行结束后会release。所以没必要传__weak self。 如果传__weak self,就无法保证block在执行时,self是否被释放,反而会出现错误。所以不能传__weak self。
The text was updated successfully, but these errors were encountered: