2014-10-09 37 views
0

我一直有问题与UITableView发送消息交易委托。 当拥有tableView的UIViewController中的dealloc被调用时,tableView仍然是活着的,并且tableView正在向它的委托发送消息。通过在tableView的所有者在dealloc中释放tableview时设置delegate = nil来解决此崩溃问题。如果内存管理是正确的,我相信这不是必须的。如何找到谁正在保留一个对象?

我想知道谁是保留tableView的方法。

有什么办法可以弄清楚吗?

谢谢!

回答

0

用仪器启动项目(菜单产品 - >配置文件 in Xcode)并选择泄漏。它将记录每个已创建,保留,释放,自动释放,释放的对象。你甚至可以在那里搜索一个内存地址。所以你需要做的就是获得你的对象的内存地址的方法,例如你可以打印它到控制台。大多数人不知道,但你可以从仪器中查看控制台:

enter image description here

2

您的tableView在其代理清理后继续处理;请记住,代表被分配到weak参考属性,因此不被UITableView保留。如果您正在折叠ViewControllerUITableView仍在加载元素,则会看到此次崩溃。如果正在释放的类是委托,最好在dealloc中分配.delegate = nil

+0

“记住,代表们被分配给弱引用属性” - 委派的UITableView设置为@财产(非原子,分配) id 委托,这就是为什么tableView仍然可以发送消息到已处理的对象。 – kazuochi 2014-10-10 14:41:34

+0

这是正确的 - 'UITableView'是在ARC之前创建的,所以你可以考虑'assign' =='weak'和'retain' =='strong'。当你的'UITableViewDelegate'被释放后,'UITableView'不再能够发送消息给对象,因为该对象不存在。但是,它可以尝试将消息发送到之前由'UITableViewDelegate'占用的内存地址处的对象;这通常会导致EXC_BAD_ACCESS。 – 2014-10-10 15:02:47

2

此崩溃通过在tableView的所有者在dealloc中释放tableview时设置delegate = nil来解决。如果内存管理是正确的,我相信这不是必须的。

,往往是真实的今天,是因为代表们经常宣称weak,这意味着当底层对象被释放,它们会自动设置为nil。但UITableView比这个更旧。它来自弧前几天及其委托声明:

@property(nonatomic, assign) id<UITableViewDelegate> delegate 

因此,如果委托被释放,UITableView将指向未分配的内存。

这种类型的崩溃通常意味着当您不在屏幕上时尝试更新您的tableview。根据我的经验,最常见的原因是当你不应该观察通知时。您希望确保您观察到viewWillAppear:中的通知,并在viewDidDisappear:期间删除所有观察结果。同样,当你离开屏幕时,你不应该观察KVO(但我更经常发现这种崩溃表明NSNotification)。

您还应该确保除委托以外的任何对象都不能直接访问tableview。没有人应该从视图/代表关系之外调用reloadData等。没有人应该访问委托人的IBOutlet属性。这些事情导致这些崩溃。委托人以外的任何人都不应该参考表格视图。

当然,确保你没有更新后台线程上的表视图。这可能不是这种情况;它往往会导致其他类型的崩溃。但这是另外一种可能性。