0

NSOperationQueueを初期化してから3つのクラス(、、、)を追加ClassAClassBClassC次々に実行するiPhoneSDK4.0コードがあります。ClassA、、ClassBおよびClassCはすべて。のサブクラスですNSOperation

関連するコードは以下に含まれています。

ClassA *classA = [[ClassA alloc] init];
ClassB *classB = [[ClassB alloc] init];
ClassC *classC = [[ClassC alloc] init];

[classB addDependency:classA];
[classC addDependency:classB];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:classA];
[queue addOperation:classB];
[queue addOperation:classC];

[classA release];
[classB release];
[classC release];
[queue release];

依存関係の理由は、操作が正常に完了したclassB場合にのみ実行する必要があるためです。classA同様に、正常に完了したclassC場合にのみ実行する必要があります。classB

現時点では、たとえば、正常に完了しなかったclassB場合に実行されないようにする方法を理解するのに苦労しています。classAこの例を続けて、私はどういうわけか[NSOperationQueue cancelAllOperations]内部から呼び起こすことを考えていましたが、内部(サブクラス)からclassA親のハンドルを取得する方法がわかりません。これは私の最初の考えだったので、同じ結果を達成するための他のより良い提案を受け入れるでしょう!NSOperationQueueclassANSOperation

各クラス内には、正しく完了したかどうかを判断するための条件付きコードがあります。現時点では、デバッグ目的でコンソールに対して「成功」または「失敗」のNSLを記録しています。NSLog(@"Fail")完璧な世界では、各クラスのステートメントを、NSOperationQueueの他のすべてのクラスの実行を停止するコードに置き換えられるようにしたいと思います。

どんな提案でも大歓迎です(そして感謝します)。

4

3 に答える 3

3

classAにプロパティを設定できます:

@property (readonly) BOOL completedSucessfully;

classAのmainメソッドの最後でこれをYESに設定します。

次に、classBの開始時に確認します。

- (void)main {
    if (NO == [[dependencies objectAtIndex:0] completedSucessfully])
        return;

これで、classAが失敗を報告した場合、classBは停止します。

注意:上記の例では、依存関係があることを確認したり、正しいクラスであることを確認したりするなど、さらに多くのエラーが必要になる可能性があります。

- (void)main {
    for (id *temp in [self dependencies])
        if ([temp isKindOfClass:[ClassA class]])
            if (NO == [(ClassA *)temp finishedSucessfully])
                return;
于 2010-07-04T10:15:43.617 に答える
1

速度が問題にならない場合は、同期して作業できることをお勧めします。それ以外の場合は、次を使用できます。

[selector:@selctor(StartB) waitUntilTaskComplete:YES];
于 2011-03-20T18:31:50.590 に答える
1

高度なNSOperationテクニック(強く推奨)に関するWWDC 2015セッションを見た後、私は自分のコードでそれらを深く使い始めました。これを達成するためのいくつかの提案があります

  1. NSOperation内から、[self currentQueue]を呼び出して、「操作を開始した操作キュー、またはキューを判別できなかった場合はnil」を取得できます。次に、返されたキューでcancelAllOperationsを呼び出すことができます。メインキューでコードを明示的に実行したり、クロージャ/ブロックにコードを入れたり、サードパーティのライブラリを呼び出したりすると、返されるキューが最初のキューではない可能性があるため、経験的にこのアプローチを使用するのは困難でした。そのような状況では、cancelAllOperationsを呼び出しても、期待される動作は発生しません。代わりに、別のキューで操作をキャンセルします。

  2. サブクラスNSOperationは、初期NSOperationQueueのプロパティを含み、サブクラスNSOperationQueueは、操作がキューに追加されたときにプロパティを設定します。次に、self.initialQueueでcancelAllOperationsを呼び出します。これは私が使用しているアプローチであり、上記のすべてのシナリオで機能します。

  3. キューレベルですべての操作をキャンセルする代わりに、操作「cancel」メソッドを呼び出して操作を終了することができます。操作がAppleの操作ガイドラインに準拠するように記述されている場合、すべての操作は開始時にisCancelledをチェックし、trueの場合は処理を中止します。これは微妙な違いです。キュー操作をキャンセルすると、開始されていない操作はまったく開始されません。操作をisCancelledに設定すると、後続の操作が開始されますが、すぐに終了する必要があります。これにより、後の操作でクリーンアップ、エラー処理、またはユーザー通知が実行される可能性があるシナリオが可能になります。

于 2015-10-08T16:04:43.293 に答える