gpt4 book ai didi

iphone - 管理对 View 退出时释放的对象的调用

转载 作者:行者123 更新时间:2023-12-03 20:48:49 25 4
gpt4 key购买 nike

我有一个在 UINavigationController 中管理的 View Controller 。我的 View Controller 显示一个“正在加载”屏幕,并使用 ASIHTTP 异步加载表数据。然后它呈现其表格,并且在每个单元格中都有一个使用 ASIHTTP 异步加载的图像。当它登陆每个图像时,它使用 [self.tableView reloadRowsAtIndexPaths] 重新加载该行,其中图像被馈送到每行中的 UIImageView。

效果很好。但是如果我在加载完成之前退出 View ,它就会崩溃。

它崩溃的地方是我的 -tableView:numberOfRowsInSection 方法,NSZombies 告诉我它死掉了,因为它要求一个名为 self 的 NSArray 的 -count .offers 已被解除分配。

该方法如下所示:

-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [self.offers count];
}

将返回包装在 if (self.offers) 中没有任何区别。

我的-dealloc 释放并设置这些属性中的每一个为nil,包括 self.offers 和 self.tableView 本身。我什至尝试设置一个 BOOL 消失 属性,在 -viewWillDisappear 中用 YES 击中它,并挂起条件行为,但它不起作用,因为 viewWillDisappear 不好像被叫了!据我所知,当导航栏弹出时,我们没有调用任何方法。

我该怎么办?

编辑:

感谢@cduhn(他正在争取支票!),我做了更多的研究。问题是,当我弹出此 View Controller 时,我的 -dealloc 没有被调用(也不是我的 -viewWillDisappear-viewDidUnload 或任何东西否则我可以用来解除这个问题根源的委托(delegate)结构)。

然后我意识到:这个 viewController 不是 NavController 堆栈上的那个!这里堆栈顶部是一个 shell View ,只是一个分段 Controller 和一个大的空 UIView。我根据分段 Controller 的状态在其他两个 UIViewController 子类之间切换该 UIView 的内容。因此,当我的父 View 上带有表格的 View 从导航堆栈中弹出时,我正在处理的这个 child 似乎没有得到任何通知。这很奇怪,因为我肯定会发布它。

我可以从我的 shell Controller 调用它的 -dealloc。就此而言,我也可以将其称为 -viewWillDisappear。我应该这样处理吗?也许我应该在 shell Controller 的 viewWillDisappear 中添加一些内容,例如:

[[self.mainView subview ] makeObjectsPerformSelector:@selector(viewWillDisappear)];

...以便该消息传播到我的 subview 。

你认为我走在正确的道路上吗?

(哦天哪...这也解释了为什么这个子 TableView 内部的操作无法到达self.navigationController!我已经对此感到困惑了好几个星期!)

最佳答案

当在委托(delegate)被释放后在委托(delegate)上调用方法时,通常会发生像这样的错误,即在对象被释放后调用该方法。避免此类错误的建议做法是,在委托(delegate)的 dealloc 方法中释放该对象之前,将对象的任何委托(delegate)(或类似委托(delegate))属性设置为 nil。我知道这是一个令人困惑的句子,所以我会根据您的错误进行解释。

您有一个异步图像下载,该下载在您退出 TableView Controller 后完成。发生这种情况时,您将调用 reloadRowsAtIndexPaths:withRowAnimation:,这会导致在表格 View 的 dataSource 上调用 tableView:numberOfRowsInSection:。此调用失败,因为该数据源不再存在。

问题是,即使您的 Controller 已被释放, TableView 对象仍然将您的 Controller 设置为其 dataSourcedelegate 属性。解决方案是简单地在 Controller 的 dealloc 中将这些属性设置为 nil,如下所示:

- (void)dealloc {
self.tableView.dataSource = nil;
self.tableView.delegate = nil;
self.tableView = nil; // Releases as a side-effect due to @property (retain)
[super dealloc];
}

现在,当您的 TableView 尝试在其数据源上调用 tableView:numberOfRowsInSection: 时,它会将消息发送到 nil 对象,该对象在 Objective C 中默默地吞下所有消息。

顺便说一句,您还应该对 ASIHTTPRequest 的委托(delegate)执行相同的操作。

每当您有一个异步操作在完成时调用委托(delegate)方法时,将该委托(delegate)设置为 nil 就尤为重要。在正常情况下使用 UITableViewController 时,您通常可以在不将 dataSource 和 delegate 设置为 nil 的情况下离开,但在这种情况下,这是必要的,因为您在 tableView 的 Controller 消失后调用其方法。

关于iphone - 管理对 View 退出时释放的对象的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3095995/

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