1

我正在浏览我的 iOS 应用程序,使用“模拟内存警告”作为我的正义之锤,这会导致一些意想不到的问题(自然)。但这是让我难过的一个问题:对象似乎不再相等。

假设我的视图控制器(我们将命名它VCBob)有……</p>

  • 两个单独的自定义UIViews子视图(让我们命名这些视图viewAviewB
    • 每个都有自己UICollectionView暴露的属性collectionView(这些UICollectionViews用作VCBob他们的delegates
  • 一个UIButton,当按下时,将其他一些视图控制器(否则无关紧要)推到堆栈上

所以我点击了,UIButton然后出现了无关紧要的视图控制器。我触发了“模拟内存警告”选项,并被VCBob编程为在 中删除viewAviewB内部-didReceiveMemoryWarning,因为它们被完全重新创建并重新插入到视图层次结构中viewWillAppear(只要它们nil在 时viewWillAppear)。这是该实现VCBob

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

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

然后我点击导航栏中的后退按钮,然后VCBob重新开始游戏。这两个自定义UIViews仍然存在,并且它们各自UICollectionViews都加载了内容。当我点击UICollectionViewCells任一集合视图中的一个时,该-collectionView:didSelectItemAtIndexPath:方法被调用VCBob;到目前为止,一切都很好。该实现看起来像这样。

- (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条件都评估为假。这是为什么?我似乎觉得我可能在做坏事didReceiveMemoryWarning。我不应该在那里处理视图吗?

4

2 回答 2

1

如果_viewA在视图层次结构中,它会被其父视图保留,所以这样做_viewA = nil不会释放它,并且当viewWillAppear方法被触发时它仍然存在。

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

所以,你应该removeFromSuperview在你的方法中添加一个调用didReceiveMemoryWarning来摆脱这个

同样的情况发生在viewB.

于 2013-05-01T20:13:16.883 回答
0

老鼠,我想我明白了。我在didReceiveMemoryWarning没有先将它们从超级视图中删除的情况下处理了我的观点。我所拥有的UIView显然仍然保留了我的陈旧对象的实例,即使我已经nil删除了它们。

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

    if (!hasSuperview) {
        [_viewA removeFromSuperview];
        _viewA = nil;
        [_viewB removeFromSuperview];
        _viewB = nil;
    }
}
于 2013-05-01T20:12:51.390 回答