2013-05-01 67 views
1

我正在通过我的iOS应用程序,使用“模拟内存警告”作为我的正义之锤,并且它引起了一些意想不到的问题(自然而然)。但是这是一个让我难以接受的问题:对象似乎不再平等。didReceiveMemoryWarning和重新构建的实例变量相等性检查

说我的视图控制器(我们将其命名为VCBob)有...

  • 两个单独定制UIViews为子视图(让我们命名这些观点viewAviewB
    • 每个都有自己的UICollectionView暴露物业collectionView(这些UICollectionViews使用VCBob作为他们delegates
  • 一个UIButton在按下时,上到堆栈

所以我轻触UIButton和这里推一些其他视图控制器(否则微不足道的一个)来了微不足道视图控制器。我点燃了“模拟内存警告”选项,并且VCBob被编程为在-didReceiveMemoryWarning内部丢弃viewAviewB,因为它们被完全重新创建并重新插入到viewWillAppear的视图层次结构中(只要它们是nil时间为viewWillAppear)。下面是VCBob该实现:

- (void)didReceiveMemoryWarning { 
    BOOL hasSuperview = self.view.superview != nil; 
    [super didReceiveMemoryWarning]; 

    if (!hasSuperview) { 
     _viewA = nil; 
     _viewB = nil; 
    } 
} 

我然后点击导航栏上的后退按钮,并VCBob回来发挥作用。这两个自定义UIViews仍然存在,并且它们各自的UICollectionViews都加载了内容。当我在任一集合视图中点击其中一个UICollectionViewCells时,将在VCBob上调用-collectionView:didSelectItemAtIndexPath:方法;到现在为止还挺好。这个实现看起来像这样。

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    if (collectionView == self.viewA.collectionView) { 
     NSLog(@"Do something here!"); 
    } else if (collectionView == self.viewB.collectionView) { 
     NSLog(@"Do something else here!"); 
    } 
} 

问题是没有任何反应 - 没有得到记录。这两个if条件评估为false。这是为什么?我似乎认为我可能会在didReceiveMemoryWarning中做坏事。我不应该在那里处理意见吗?

回答

1

如果_viewA是在一个视图层次,它是由它的父保留,这样做_viewA = nil不会释放它,它依然存在,当viewWillAppear方法被炒鱿鱼。

然后,在您的viewWillAppear中,您正在添加一个viewA的“重复”,其中有自己的collectionView,放在原来的一个上面:您看到一个视图,但实际上它们是两个视图重叠。

所以,你应该在你的didReceiveMemoryWarning方法添加removeFromSuperview呼吁摆脱这种

同样的情况,为viewB

+0

你得出了我所做的确切结论,并在发布我的报告后发布了一个瞬间。但既然你不是我,我会给你答案的功劳! – 2013-05-01 20:18:06

+0

阿哈哈谢谢:)用英文写作需要我太多时间,我必须仔细检查每一个单词我键入..如果我可以在意大利回答我会更快:) – 2013-05-01 20:20:43

+0

我想如果我可以阅读意大利语,我也会是一个更好的人。谢谢,亚历山德罗! (顺便说一下,你的英语很好。) – 2013-05-01 20:32:36

0

大鼠,我想我想通了。我在didReceiveMemoryWarning中处理了我的观点,而没有先从超级视角中移除它们。我所在的UIView显然仍然保留着我的陈旧物品的实例,尽管我已将它们排除在外。

- (void)didReceiveMemoryWarning { 
    BOOL hasSuperview = self.view.superview != nil; 
    [super didReceiveMemoryWarning]; 

    if (!hasSuperview) { 
     [_viewA removeFromSuperview]; 
     _viewA = nil; 
     [_viewB removeFromSuperview]; 
     _viewB = nil; 
    } 
}