1

「Simulate Memory Warning」を正義のハンマーとして使用して、iOS アプリを調べていますが、(当然のことながら) 予期しない問題が発生しています。しかし、これは私を困惑させた 1 つの問題です。オブジェクトは、一見、等しくないように見えます。

私のView Controller(名前を付けますVCBob)が…</p>

  • サブビューとしての2 つの個別のカスタム(これらのビューとUIViews名前を付けましょう) viewAviewB
    • それぞれ独自UICollectionViewのプロパティとして公開されていますcollectionView(これらは としてUICollectionViews使用VCBobされますdelegates)
  • 押されたUIButtonときに、他のView Controller(それ以外の場合は重要でないもの)をスタックにプッシュする

をタップするUIButtonと、意味のないView Controllerが表示されます。「Simulate Memory Warning」オプションを起動し、完全に再作成されてビュー階層に再挿入されるため (の時点である限り) 、の内部VCBobを破棄するようにプログラムされています。での実装は次のとおりです。viewAviewB-didReceiveMemoryWarningviewWillAppearnilviewWillAppearVCBob

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

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

次に、ナビゲーション バーの [戻る] ボタンをタップすると、VCBobプレイに戻ります。2 つのカスタム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条件は両方とも false と評価されます。何故ですか?で悪いことをしているかもしれないと思っているようですdidReceiveMemoryWarning。そこでビューを処分するべきではありませんか?

4

2 に答える 2

1

_viewAビュー階層にある場合、スーパービューによって保持されるため、解放されず、メソッドが起動_viewA = nilされてもそこに残ります。viewWillAppear

次に、独自の collectionView を内部に追加して、元のビューのすぐ上に配置しviewWillAppearた の「複製」を追加します。1 つのビューが表示されますが、実際には 2 つのビューが重なっています。viewA

したがって、これを取り除くには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 に答える