- (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'作为块中的强引用,这段代码可以吗?或者在这种情况下如何避免泄漏?
答案 0 :(得分:0)
在块中提到时自动保留对象。当块被解除分配时,它们被释放。所以这段代码没问题。当你的自我对象拥有自我内部的所有块时,就会出现问题。 因此,您只需要在不再需要时释放阻止。
答案 1 :(得分:0)
此代码中有一个保留周期,因为self
保留self.downloadQueue
(以及其他队列),它会保留调度给它的所有块,包括此处的块,而后者又保留{ {1}}复制时(在将其分派到队列时发生)。
但是,它是临时保留周期,因为一旦在队列上执行了块,队列将(希望)释放它,打破循环。
答案 2 :(得分:0)
不,self
不会泄漏。但是,self
将保留到最后一个块执行完之后。当最后一个块完成时,该块将被释放,然后释放self
。那时,只有IFF没有其他强引用self
,它将被解除分配。
编辑:
我忍不住提到这一点(因为样品来自苹果公司 - 如果是盐则带上谷物;)
所以,在最顶层有方法downloadFromRemoteService
。很明显,这是一个网络请求。网络请求本身就是 _asynchronous_。
异步操作的一个属性是不能再以真实的方式使该操作“同步”。一旦异步 - 总是异步。
从代码示例中可以明显看出,网络请求非常奇怪同步,哦!
将异步任务包装到同步包装器中会发生什么?好吧,它至少是“次优”:调用线程将立即被阻塞,直到结果可用,然后返回结果。这对资源来说是一个相当大的浪费(线程有限,创建成本高,需要大量的RAM)。
因此,此代码具有“代码味道”。这是一个“糟糕的编程习惯”。我们应该做得更好。 ;)