代码之家  ›  专栏  ›  技术社区  ›  Dan Ray

管理对在视图退出时取消分配的对象的调用

  •  2
  • Dan Ray  · 技术社区  · 14 年前

    [self.tableView reloadRowsAtIndexPaths] 重新加载该行,在该行中,图像被馈送到每行的UIImageView。

    它崩溃的地方就在我的房间里 -tableView:numberOfRowsInSection 方法,NSZombies告诉我它死了,因为它要求 -count 一个叫做 self.offers 已经解除分配。

    该方法如下所示:

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

    把那个回路包起来 if (self.offers) 没什么区别。

    -dealloc 释放并将这些属性中的每一个设置为nil,包括self.offers和self.tableView本身。我甚至试着建立一个 BOOL disappearing 属性,用“是”键点击 -viewWillDisappear ,并将条件行为挂起,但它不起作用,因为viewwillexamine似乎没有被调用!据我所知,当导航栏弹出时,我们不会调用任何方法。

    我该怎么办?

    编辑:

    多亏了@cduhn(他在为一张支票而努力!),我看了很多。问题是,我的 只是当我弹出这个viewcontroller(或者我的 -视图将消失 也不是 -viewDidUnload 或者任何我可以用来解开这个问题根源的委托结构的东西)。

    然后我意识到:这个viewController不是NavController堆栈上的那个!在堆栈顶部的是一个shell视图,只是一个分段的控制器和一个大的空UIView。根据分段控制器的状态,我在另外两个UIViewController子类之间切换该UIView的内容。因此,当我的视图和它的父视图上的表从nav堆栈中弹出时,我正在处理的这个子视图似乎没有得到任何关于它的通知。这很奇怪,因为我肯定 release 把它弄得乱七八糟。

    我可以从shell控制器调用它的-dealloc。我可以称之为它的-视图也会消失。我应该这样处理吗?可能我应该在shell控制器的视图中添加一些内容,例如:

    …这样消息就会传播到我的子视图。

    你觉得我在这条路上对吗??

    (哦,天哪。。。这也解释了为什么子表视图中的操作无法访问 self.navigationController ! 几个星期来我一直对此感到困惑!)

    2 回复  |  直到 14 年前
        1
  •  4
  •   cduhn    14 年前

    类似这样的错误,方法在对象被释放后被调用,通常发生在方法在委托被释放后被调用时。避免此类错误的建议做法是,在委托的代理中释放对象之前,将对象的任何委托(或类似委托)属性设置为nil dealloc

    您有一个异步映像下载,在退出表视图控制器后完成。当这种情况发生时,你是在打电话 reloadRowsAtIndexPaths:withRowAnimation: tableView:numberOfRowsInSection: 在表视图的 dataSource . 此调用失败,因为该数据源不再存在。

    数据源 delegate 属性,即使控制器已解除分配。解决方法是在控制器的 释放内存 ,如下所示:

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

    现在当您的表视图试图调用 表View:numberOfRowsInSection: 在它的数据源上,它将消息发送到nil对象,nil对象在Objective C中默默地吞下所有消息。

    顺便说一下,你也应该对你的ASIHTTPRequest的委托做同样的事情。

    每当异步操作在完成时调用委托方法时,将该委托设置为nil尤其重要。在正常情况下使用UITableViewController时,通常不需要将dataSource和delegate设置为nil,但在这种情况下,这是必要的,因为您是在tableView的控制器消失后对其调用方法。

        2
  •  0
  •   Stone Mason    14 年前

    我建议堆栈弹出不是这里的问题。