当“自我”出现在街区时,它绝对是泄密吗?

时间:2013-09-02 09:10:42

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

- (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, ^{
                [self renderThumbnail:img];

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

这是来自Apple WWDC2012的代码“带块的异步设计模式,GCD和”,'self'作为块中的强引用,这段代码可以吗?或者在这种情况下如何避免泄漏?

3 个答案:

答案 0 :(得分:0)

在块中提到时自动保留对象。当块被解除分配时,它们被释放。所以这段代码没问题。当你的自我对象拥有自我内部的所有块时,就会出现问题。 因此,您只需要在不再需要时释放阻止。

答案 1 :(得分:0)

此代码中有一个保留周期,因为self保留self.downloadQueue(以及其他队列),它会保留调度给它的所有块,包括此处的块,而后者又保留{ {1}}复制时(在将其分派到队列时发生)。

但是,它是临时保留周期,因为一旦在队列上执行了块,队列将(希望)释放它,打破循环。

答案 2 :(得分:0)

不,self不会泄漏。但是,self将保留到最后一个块执行完之后。当最后一个块完成时,该块将被释放,然后释放self。那时,只有IFF没有其他强引用self,它将被解除分配。

编辑:

我忍不住提到这一点(因为样品来自苹果公司 - 如果是盐则带上谷物;)

所以,在最顶层有方法downloadFromRemoteService。很明显,这是一个网络请求。网络请求本身就是 _asynchronous_。

异步操作的一个属性是不能再以真实的方式使该操作“同步”。一旦异步 - 总是异步。

从代码示例中可以明显看出,网络请求非常奇怪同步,哦!

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

因此,此代码具有“代码味道”。这是一个“糟糕的编程习惯”。我们应该做得更好。 ;)