假设您的控制器是一个表视图,并且您将要执行长度任务(例如下载缩略图)以在单元格中查看。通常情况下,您可以让网络调用在完成下载后对控制器进行回调。然后回调可以重新加载表或进行其他形式的UI更新(隐藏微调器等)。
但是,如果控制器被卸载怎么办?假设用户离开此控制器并且已被释放?怎么了?尽管控制器现在不在内存中,回调是否仍然有效?此外,如果回调对某些对象(比如UITableView)进行操作,那么在取消分配控制器时会发生什么?我想控制器可以释放所有对象,回调只是在nil上调用方法以防止崩溃。但这是惯例吗?
答案 0 :(得分:2)
一般来说,如果异步方法采用某种目标/动作回调,它应该保持对目标的引用,这样它可以确保它在触发回调时仍然存在。
另一方面,对于不的类的代表来说,它通常是常规的;在这种情况下,调用类确保它自己作为dealloc方法中其他任何东西的委托来删除它是至关重要的。
这是一个简单的例子,涉及一个UIViewController,它充当NSURLConnection的委托。虽然代理通常是分配而不是保留,但NSURLConnection将在您作为代理传递时保留视图控制器。在连接完成/取消/出错之前,它不会释放它。
// connection is an instance variable in your controller sub-class
connection = [[NSURLConnection alloc] initWithRequest:someRequest delegate:self];
// implement various NSURLConnectionDelegate methods etc.
由于它被保留,因此在连接完成之前,您的视图控制器不应被解除分配。
那么通常情况下,何时不保留代表呢?这意味着某些东西可能会导致您的视图控制器在任何对象使用它之前被释放和解除分配。您的视图控制器有责任通过将委托重置为nil来确保不会发生这种情况:
someDownloadManager = [[MyDownloadManager alloc] init];
someDownloadManager.delegate = self; // delegate is an assigned property
[someDownloadManager startDownloading];
在你的视图控制器的dealloc中:
- (void)dealloc
{
someDownloadManager.delegate = nil; // this is important
[someDownloadManager release]; // it might still be retained by something else!
[super dealloc];
}
出于同样的原因,如果你的对象将自己注册为NSNotificationCenter的观察者,它也应该在dealloc方法中将自己作为观察者删除。
这有帮助吗?
答案 1 :(得分:1)
解决在未加载tableView时数据到达的问题:
在数据对象模型范例中,不必加载视图以便接受和存储数据。稍后再次查看视图(表格或其他内容)时,它应该可以获取数据(如果可用)。在tableViewController类的viewWillAppear中调用UITableView reloadData有时候是一个好主意,只取决于你的架构。
解决视图IS可见和加载时数据到达的问题: 数据到达并可用后,循环访问TableViewControllers并向其发送“reloadData”。