gpt4 book ai didi

objective-c - 保护我的代码免受来自完成 block 的僵尸

转载 作者:可可西里 更新时间:2023-11-01 05:00:19 27 4
gpt4 key购买 nike

我熟悉委托(delegate)模式和取消我的委托(delegate),尤其是在执行异步调用时,当我的 View Controller 消失时这些调用仍在进行中。我 nil 委托(delegate),回调成功返回 nil 对象。

我现在正在尝试使用完成 block 来使我的代码更易于阅读。

我从我的 View Controller 调用网络服务,并传递一个更新我的 UITableView 的 block 。在正常情况下,它工作正常。但是,如果我在 View 完成之前离开 View ,则会执行完成处理程序 block - 但 UITableView 现在是一个僵尸。

通常的处理模式是什么?

更新代码示例

这是一个 iPad 应用程序,我在屏幕上同时有两个 View Controller ,就像一个 Split View。一个是细节,另一个是图像网格。我单击一个图像,它告诉详细信息以加载信息。但是,如果我在图像有机会进行网络调用之前点击图像的速度太快 - 我就会遇到问题。在更改图像时,将调用下面的代码来计算图像的收藏夹....

所以这是我的困境,如果我使用下面的代码 - 它工作正常,但如果您在网络响应之前切换图像,它会在仪器中泄漏。

如果我删除 __block 并传入 self,那么它会因僵尸而崩溃。

我赢不了...我确定我错过了一些关于使用 block 的基本知识。

__block UITableView *theTable = [self.table retain];
__block IndexedDictionary *tableData = [self.descriptionKeyValues retain];
FavouritesController *favourites = [Container controllerWithClass:FavouritesController.class];
[favourites countFavouritesForPhoto:self.photo
completion:^(int favesCount) {

[tableData insertObject:[NSString stringWithFormat:@"%i", favesCount]
forKey:@"Favourites:" atIndex:1];
[theTable reloadData];

[tableData release];
[theTable release];
}];

有什么建议吗?谢谢

第二次更新

我改变了加载收藏夹的方式。我不再将收藏夹设为单例,而是在每次更改照片时创建一个实例。通过替换它并杀死旧的 - 该 block 无处可回调(我猜它甚至不存在)并且我的代码现在看起来如下所示,并且它似乎可以正常工作:

[self.favourites countFavouritesForPhoto:self.photo 
completion:^(int favesCount) {
[self.descriptionKeyValues insertObject:[NSString stringWithFormat:@"%i", favesCount]
forKey:@"Favourites:" atIndex:1];
[self.table reloadData];
}];

它没有泄漏,也没有崩溃。

最佳答案

我建议你在 block 的开头测试 tableview 不是 nil。听起来 tableview 在其父 View 离开屏幕时被正确丢弃,所以在那之后,没有 tableview 操作有效。

将 UITableView 保留在 block 中不是一个好主意,因为数据源/ TableView 更新可能会导致隐式方法调用和通知,如果 TableView 不在屏幕上,这些调用和通知将不相关。

关于objective-c - 保护我的代码免受来自完成 block 的僵尸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9341708/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com