0
- (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,这段代码可以吗?或者在这种情况下如何避免泄漏?</p>

4

3 回答 3

0

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

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

于 2013-09-02T23:12:03.800 回答
0

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

于 2013-09-02T13:56:05.307 回答
0

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

编辑:

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

所以,在最上面有方法downloadFromRemoteService。很明显,这是一个网络请求。网络请求本质上是_异步_。

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

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

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

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

于 2013-09-03T17:14:35.133 回答