4

NSOperationonを使用してバックグラウンド スレッドで検索を実装しようとしていiOSます。サブクラス化したくなかったNSOperationので、これが私がやっていることです:

[searchQueue cancelAllOperations];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self
                                                                  elector:@selector(filterContentForSearchText:)
                                                                   object:self.searchDisplayController.searchBar.text];
[searchQueue addOperation:op];
[op release];

search メソッドには、検索対象が配列内にあるかどうかをチェックする for ループが含まれています。NSOperationを呼び出して をキャンセルするとcancelAllOperations、for ループは引き続き配列を処理します。これを防ぎたいのですが、for ループ内からこれを呼び出すことが正当かどうか疑問に思っていました。

if ([[[searchQueue operations] objectAtIndex:0] isCancelled]) {
    [tmp_array release];   // tmp_array is used to hold temporary results
    [pool drain];          // pool is my autorelease pool
    return;
}
4

1 に答える 1

8

サブクラス化する理由の 1 つは、NSOperation適切なキャンセルを実装することです。あなたのアプローチを行うこともできますが、それはいくつかの優れた設計原則に違反しています。基本的に、キャンセルには操作自体の協力が必要なため、実行中のメソッドは呼び出し方法について何も認識してはならないため、NSInvocationOperation既に実行されている間に呼び出しをキャンセルするようには構築されていません (ただし、実行を開始するにキャンセルすることはできます)。 .

代わりに、 をサブクラスNSOperation化すると、この機能のほとんどをmainメソッドに簡単に組み込むことができます。

@implementation MyOperation
- (void)main {
    if ([self isCancelled])
        return;

    for (...) {
        // do stuff

        if ([self isCancelled]) {
            [tmp_array release];
            return;
        }
    }
}

@end

このような実装では、独自の自動解放プールを維持する必要がないことにも注意してください。

于 2010-12-20T18:58:01.533 に答える