7

目標は、「テーブルビューを表示する前にデータをロードする viewWillAppear の開始時にスピナー グラフィックを起動する」ことであり、ユーザーはテーブルを表示する前に遅延がある理由を不思議に思うことはありません。つまり、UIActivityIndi​​catorView がウィンドウに追加されたので、それを非表示/表示するようにアルファを設定したいだけです。

viewWillAppear のロード/計算に進む前に、スレッドを開始して「回転する歯車」イメージビュー (tag=333) が表示されることを確認すると、この奇妙なエラーが発生します。

[appdel addGearz] と [appdel removeGearz] のすべての呼び出しで取得できるわけではありません。これらの両方で発生し、ランダムです。これは、viewWillAppears の 2 回後、または 15 回後に発生する可能性があります。アルファを設定する行をコメントアウトすると、すべてが機能します。

典型的な viewWillAppear は次のようになります。

[super viewWillappear];
self.title=@"Products listing"; //and other simple things
[appdel addGearz];
[self getProducts];
[self getThumbnails];
[myTableView reloadData]; //in case view already loaded and coming back from subview and data changed

.alpha の行がコメントアウトされていない場合にクラッシュするコードは次のとおりです。

-(void)addGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOn) toTarget:self withObject:nil];
}

-(void)removeGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOff) toTarget:self withObject:nil];
}

- (void)gearzOn {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=1.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

- (void) gearzOff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=0.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

私は他の誰かのコードを使用したことがあります。確かに、スレッド内の UIView のアルファを変更できる必要がありますか? 「これを変更している間は列挙を停止する」コードにアルファ変更を「埋め込む」必要がありますか?

そのアルファ変更行をプール割り当ての上または[プールドレイン]の下に移動することでクラッシュしないようにしましたが、「プールが配置されていない状態で自動解放されました-ちょうどリークしています」というメッセージがたくさん表示されます。

どうやら、このスレッド コードについて理解できないことがあります。

4

1 に答える 1

8

別のスレッドで UI を変更しようとしないでください。UI はメイン スレッドでのみ操作する必要があります。

新しいスレッドをデタッチする代わりに、performSelectorOnMainThread:withObject:waitUntilDone:. これにより、メソッドが適切なスレッドで呼び出されることが保証されます。

于 2011-01-21T11:11:01.870 に答える