在块中捕获自我(保留周期),并非总是如此?

Dan*_*iel 6 block objective-c

以下代码来自Apple提供的LazyTableImages示例代码(源自此处).

在他们的完成块中,他们有一个引用self的引用保留周期...但是我没有在Xcode中得到这个警告,而在我的类似代码中我会这样做.

它是否正确?

也许我错过了这个细微之处.

- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
    IconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
    if (iconDownloader == nil) 
    {
        iconDownloader = [[IconDownloader alloc] init];
        iconDownloader.appRecord = appRecord;
        [iconDownloader setCompletionHandler:^{

            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

            // Display the newly loaded image
            cell.imageView.image = appRecord.appIcon;

            // Remove the IconDownloader from the in progress list.
            // This will result in it being deallocated.
            [self.imageDownloadsInProgress removeObjectForKey:indexPath];

        }];
        [self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
        [iconDownloader startDownload];  
    }
}
Run Code Online (Sandbox Code Playgroud)

Abi*_*ern 4

您认为您看到的保留周期是因为该对象将下载器保存在字典中。

确实,块中存在对 self 的强引用,但是,只要完成处理程序始终运行,下载程序就会从字典中删除。最终这个字典将是空的,这意味着不会有任何对象持有 self,因此没有保留周期。

  • 编译器使用命名约定来决定是否警告潜在的保留周期,比较[Clang - 从命名约定中阻止保留周期?](http://stackoverflow.com/questions/15535899/clang-blocks-retain-cycle -来自命名约定)。 (2认同)