我一直遇到UITableView向dealloced委托发送消息的问题。 当调用拥有tableView的UIViewController中的dealloc时,tableView仍处于活动状态,tableView正在向其委托发送消息。当tableView的所有者在dealloc中释放tableview时,通过设置delegate = nil来解决此崩溃。我相信如果内存管理正确完成,这是不必要的。
我想知道找出谁保留tableView的方法。
有什么方法可以解决这个问题吗?
谢谢!
答案 0 :(得分:2)
您的tableView
在其代表被清理后继续处理;请记住,委托被分配到weak
引用属性,因此不会被UITableView
保留。如果在ViewController
仍在加载元素的同时折叠UITableView
,则会看到此崩溃。如果要解除分配的类是委托,最好在dealloc中分配.delegate = nil
。
答案 1 :(得分:2)
当tableView的所有者在dealloc中释放tableview时,通过设置delegate = nil来解决此崩溃。我相信如果内存管理正确完成,这是不必要的。
今天通常都是这样,因为委托经常被声明为weak
,这意味着当底层对象被释放时它们会自动设置为nil
。但UITableView
比这更早。它来自ARC之前的日子,其代表被宣布:
@property(nonatomic, assign) id<UITableViewDelegate> delegate
因此,如果代理被解除分配,UITableView
将指向未分配的内存。
此类崩溃通常意味着您在不在屏幕上时尝试更新您的桌面视图。根据我的经验,最常见的原因是在你不应该的时候观察通知。您希望确保在viewWillAppear:
中观察通知,并在viewDidDisappear:
期间删除所有观察结果。同样地,当你在屏幕外时,你不应该观察KVO(但我经常发现这种崩溃表明NSNotification
)。
您还应该确保委托以外的任何对象都不能直接访问tableview。没有人应该从视图/委托关系之外调用reloadData
或类似的东西。没有人应该访问代表的IBOutlet属性。这些事情导致了这些类型的崩溃。代表之外的任何人都不应该引用表视图。
当然,请确保您不在后台线程上更新表视图。这可能不是这样的;它往往导致其他类型的崩溃。但这是另一种可能性。
答案 2 :(得分:0)
使用Instruments启动项目(Xcode中的菜单 Product-&gt; Profile )并选择 Leaks 。它将记录已创建,保留,释放,自动释放,取消分配的每个对象。你甚至可以在那里搜索一个内存地址。所以你需要做的就是获取对象的内存地址,例如你可以把它打印到控制台。大多数人不知道,但你可以从仪器内查看控制台: