【问题标题】:Is it absolutely leaks when "self" appeared in block?当“自我”出现在块中时,它是否绝对泄漏?
【发布时间】:2013-09-02 09:10:42
【问题描述】:
- (void)netServiceDidResolveAddress:(NSNetService *)service {
    dispatch_async(self.downloadQueue, ^{
        NSData *data = [self downloadFromRemoteService:service];

        dispatch_async(self.storeQueue, ^{
            int img = [self.imageStore addImage:data];

            dispatch_saync(self.renderQueue, ^{
                [自我渲染缩略图:img];

                dispatch_async(dispatch_get_main_queue(), ^{
                    [[self thumbnailViewForId:img] setNeedsDisplay:YES];
                });
            });
        });
    });
}

这是Apple WWDC2012《Asynchronous Design Patterns with Blocks, GCD, and》的代码,'self' as strong reference in blocks,这段代码可以吗?或者在这种情况下如何避免泄漏?

【问题讨论】:

    标签: ios objective-c memory-leaks block grand-central-dispatch


    【解决方案1】:

    不,self 不会泄露。但是,self 将保留到执行完最后一个块之后。当最后一个块完成时,该块被释放,从而释放self。那时,只有 IFF 没有其他对 self 的强引用,它将被释放。

    编辑:

    我忍不住要提到这一点(因为样品来自 Apple 本人——如果有盐,请与谷物一起食用;))

    所以,在最顶部有方法downloadFromRemoteService。很明显,这是一个网络请求。网络请求是固有的_异步_。

    异步操作的一个属性是该操作不能再以真正的方式“同步”。一次异步 - 始终异步。

    从代码示例中也很明显,网络请求非常奇怪同步,哦!

    将异步任务包装到同步包装器时会发生什么?好吧,它至少是“次优的”:调用线程将立即被阻塞,直到结果可用,然后才返回结果。这对资源来说是相当大的浪费(线程是有限的,创建成本很高,并且需要大量的 RAM)。

    所以,这段代码有“代码味道”。这是一种“糟糕的编程习惯”。我们应该把它做得更好。 ;)

    【讨论】:

      【解决方案2】:

      在块中提及时自动保留的对象。他们在块被释放时被释放。所以这段代码没问题。当您的自我对象拥有内部具有自我的这些块时,就会出现问题。 所以当你不再需要它时,你只需要释放它。

      【讨论】:

      • 这实际上是一个正确答案(+1)为了平衡。责怪无知;)
      【解决方案3】:

      这段代码中有一个retain循环,因为self保留了self.downloadQueue(和其他队列),它保留了所有分派给它的块,包括这里的块,它反过来又保留了self被复制(当它被分派到队列时发生)。

      但是,这是一个临时保留循环,因为一旦块在队列上执行,队列就会(希望)释放它,从而打破循环。

      【讨论】:

        猜你喜欢
        • 2022-09-27
        • 2012-11-11
        • 2012-01-23
        • 2012-01-23
        • 2016-08-16
        • 2011-05-16
        • 2011-04-24
        • 1970-01-01
        • 2012-01-31
        相关资源
        最近更新 更多