0

配列から未使用のページを削除する際に問題があります。

NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [descriptionsList count]; i++) {
        [controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];

私はオブジェクトを追加しています:

- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= [descriptionsList count]) return;
    // replace the placeholder if necessary
    DetailsView *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[DetailsView alloc] initWithElement:[descriptionsList objectAtIndex:page]
                                                 andFrame:CGRectMake(320*page, 0, 320, 420)];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (nil == controller.superview) {
        [scrollView addSubview:controller];
    }
}

そして私はこれを使ってページを削除して作成しています:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;

    //load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            if ([viewControllers objectAtIndex:i] != nil) {
                [[viewControllers objectAtIndex:i] release];
                [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            [self loadScrollViewWithPage:i];
        }
    }
}

ページ3を表示したいときに、アプリが頻繁にクラッシュします。これをどのように行うべきかについてのアドバイスはありますか?ありがとう。

4

3 に答える 3

2

いくつかの問題:

  • NSArrays は「nil」オブジェクトを格納できないため、!= nil のチェックは常に成功するため、必要ありません。
  • 配列内のオブジェクトを解放するべきではありません。対応する -retain メッセージがありません。それにもかかわらず、配列はそれに入れられたオブジェクトを自動的に保持し、それらが削除されるとそれらを解放します
  • あなたの命名法は少し混乱しています。viewControllers と呼ばれる配列と controller と呼ばれるオブジェクトがありますが、これらは両方ともビューのように見えます (initWithFrame を使用しているため)。
于 2009-11-08T14:53:39.030 に答える
1

この行:

if ([viewControllers objectAtIndex:i] != nil)

nil と評価されない NSNULL オブジェクトが配列に取り込まれているため、常に TRUE と評価されます。インデックスにビューが格納されている場合でも、ブロックは実行されます。このブロックは、配列全体にNSNullオブジェクトを設定し、すべてのビューを一掃します。ビューへの後続の呼び出しはすべてクラッシュします。

ここの設計が悪いと思います。ビューを配列に入れるべきではありません。代わりに、データを配列に入れてから、いつでも表示するデータに基づいて再利用可能なビューを設定する必要があります。「UITable」が再利用可能な「UITableViewCells」でどのように表示されるかを見てください。

于 2009-11-08T17:52:48.177 に答える
-1

遅延読み込みを使用したこのアプローチは、実際には良い本から入手しましたが、サンプルは非常に単純なビューであり、それらを解放していませんでした。ページの初期化は scrollViewDidScroll メソッドで行われましたが、これは私のコンテンツ (写真と 2 つのテキスト) でデバイスを完全に混乱させました。使用されているメモリがアプリをクラッシュさせているため、3 ページだけをロードしたままにします。更新されたコードは次のとおりですが、オブジェクトを解放したり、ビューから削除したりできないため、重複が発生します。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            DetailsView *controller = [viewControllers objectAtIndex:i];
            if ((NSNull *)controller != [NSNull null]) {
                if (nil != controller.superview) {
                    NSLog(@"remove from superview %d", i);
                    //[controller.superview removeFromSuperview];
                }
                [viewControllers removeObjectAtIndex:i];
                [viewControllers insertObject:[NSNull null] atIndex:i];
                //[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            NSLog(@"allocating %d", i);
            [self loadScrollViewWithPage:i];
        }
    }
}

再利用可能なビューを 2 つしか使用していない場合、フラッシュなしでリアルタイムでビューを作成できますか? 2 つのビューのサンプルを見たことがありますが、コンテンツが存在する必要があるとのことでした。

于 2009-11-08T20:41:20.700 に答える