2

私は iOS 開発が初めてで、マルチスレッドの問題に直面しています。

KTPhotobrowserSDWebImageを使用して、写真とビデオのギャラリーを作成しています。各画像に外部データをロードする必要があり、ギャラリーのスクロール ビューの滑らかさに影響を与えたくありません。

NSOperationそのため、 andを使用してそれを実行しようとしていますが、NSOperationQueue正しく行っているかどうかはわかりません。

私が望むのは、ユーザーが画像にとどまらずスクロールし続けない場合、読み込みプロセスを停止することです。

私の現在のコード:

//setCurrentIndex is called when the scrollView is scrolled

- (void)setCurrentIndex:(NSInteger)newIndex {

   [loadingQueue_cancelAllOperations]; 
   currentIndex_ = newIndex;
   [self loadPhoto:currentIndex_];     
   NSInvocationOperation *InvocationOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadInfosAtIndex:) object:newIndex];

   [loadingQueue_ addOperation:InvocationOp];      
   [InvocationOp release];

   [selfloadPhoto:currentIndex_ + 1];
   [selfloadPhoto:currentIndex_ - 1];
   [selfunloadPhoto:currentIndex_ + 2];
   [selfunloadPhoto:currentIndex_ - 2]; 
}

-(void) loadInfosAtIndex:(NSInteger)index {

   if (index < 0 || index >= photoCount_) {
        return;
   }

   KTPhotoView* photoView = [photoViews_ objectAtIndex:index];
   if([photoView infosAlreadyLoaded]){
       NSLog(@"%d Already Loaded", index);
       return;
   }

    //Get the extra information by calling a web service
    photoView.infosAlreadyLoaded = YES;
}

これは適切な方法ではないと思います...誰かアドバイスはありますか?

4

2 に答える 2

3

不確実な状態になる可能性があるスケジューリングベースのキャンセルに頼る代わりに、アトミックアクセスを持つキャンセルインスタンス変数を使用します (アトミックプロパティまたはミューテックスを使用した BOOL ivar のいずれかを介して)。

次に、[loadingQueue_cancelAllOperations] の代わりに、キャンセル フラグを YES に設定し、loadInfosAtIndex で定期的にチェックします。これは基本的にキャンセルのポーリングであり、コードが関係している場合は面倒です。ただし、フラグを読み取ることでキャンセルを適切に処理できるという利点があります。処理の一環として、isRunning フラグ (アトミック/ミューテックスも必要) を NO に設定し、戻ることでスレッドを終了できます。

メイン スレッドでは、キャンセル フラグを YES に設定した後、新しいスレッドを開く前に isRunning フラグが NO になるまで待つことができます。

于 2013-02-05T11:16:15.493 に答える
-1

[loadingQueue_ cancelAllOperations] は、操作をすぐにキャンセルするのではなく、まだ実行を開始していないキュー内の操作のみをキャンセルします。

キュー内の操作がすでに開始されている場合は、操作が完了した後にのみ削除されます。cancelAllOperations の詳細

現在実行中のブロックを削除する場合は、GCD async を使用することをお勧めします。

于 2013-02-05T09:21:43.417 に答える