アップルのNSOperationによると、並行操作ではmain
、同時操作ではstart
メソッドをオーバーライドする必要があります。しかし、なぜ?NSOperation、開始対メイン
答えて
私は、コンカレント対ノンコンカレントは単なるフラグではなく、非常に大きな違いだと思います。 2つの異なるメソッドを持つことによって、非並行のものを使用する必要がある場合に並行操作を使用しないこと、またはその逆を行うことを絶対に確実にします。
あなたが間違っている場合、あなたのコードはこの設計のために絶対に動作しません。それはあなたがすぐにそれを修正するので、あなたが望むものです。メソッドが1つしかなかった場合は、非並行ではなく並行を使用すると、非常に微妙なエラーが発生する可能性があります。また、同時実行ではなく非同時実行では、パフォーマンス上の問題が発生する可能性があります。
まず、「同時」および「非同時」は、人々を混乱させる傾向があり(「非同期/同期」と同義語として使用される)、幾分特殊な意味を持つことに注意してください。 「並行」とは、「オペレーションがそれ自身の並行性と状態を管理する」ことを意味します。 「非並行」とは、「操作は並行性を管理するために他のもの(通常はキュー)を必要とし、デフォルトの状態処理が必要です」という意味です。
start
はすべてデフォルトの状態処理を行います。その部分はisExecuting
に設定し、次にmain
を呼び出し、main
が返ってくるとisExecuting
をクリアし、isFinished
に設定します。自分の状態を処理しているので、あなたはそれを望んでいません(main
を終了して操作を終了したくない場合)。したがって、start
を実装し、super
を呼び出さないといけません。必要ならばmain
メソッドを使用できますが、すでにstart
をオーバーライドしています(それはmain
というものです)。ほとんどの人はすべてのコードをstart
に入れています。
一般的に、並行操作は使用しないでください。彼らはあなたが意味することはめったにありません。彼らはは間違いなくは「バックグラウンドで動くもの」を意味するものではありません。どちらの種類の操作もバックグラウンドで実行できます(また、にはがバックグラウンドで実行されません)。問題は、デフォルトのシステム動作(非並行)か、すべてを自分で処理する(同時)かどうかです。
それを自分で処理するという考え方が「NSThread
をスピンアップする」なら、あなたはそれを必要とするC/C++ライブラリとインターフェースするためにこれをやっていない限り、間違いを犯していると思います。それはキューを作成している場合は、おそらくそれを間違っている(NSOperationはこれを避けるためのすべての種類の機能があります)。 「バックグラウンドで手動で処理する」のようなものなら、おそらく間違っているでしょう。デフォルトの(並行していない)動作は、あなたがやろうとしている動作よりもほぼ確実に優れています。
並列処理が役立つのは、使用しているAPIがすでに並列処理を処理している場合です。 main
が返されると、非並行操作が終了します。だから、もしあなたの操作がNSURLConnection
のような非同期のものを包むならば?これを処理する1つの方法は、ディスパッチグループを使用し、main
の最後にdispatch_wait
を呼び出して、すべてが完了するまで返さないようにすることです。それで大丈夫です。私はいつもそれをする。しかし、ブロックされていないスレッドはブロックされてしまい、リソースが浪費され、複雑なコーナーケースでデッドロックが発生する可能性があります(実際にはです)。Appleは可能だと言っていますが、それを目的にさえも起こすことができる)。
これを実行する別の方法は、自分自身を同時操作として定義し、NSURLConnection
代理人メソッドで手作業でisFinished
を設定することです。 Dispatch I/Oのような他の非同期インターフェイスをラッピングしている場合、同様の状況が発生し、並行処理がより効率的になる可能性があります。
(理論的には、並行操作は、キューを使用せずに操作を実行する場合にも役立ちます。これは意味があるところで非常に畳み込まれたケースを想像することはできますが、そのボートでは、あなたが何をやっているのか分かっていると思います)。
しかし、何か質問がある場合は、デフォルトの非並行動作を使用してください。ほとんどの場合、(特にディスパッチグループを使用する場合は)ほとんど手間をかけずにそのような振る舞いを得ることができます。次に、ドキュメント内の「並行」というやや混乱した説明の周りに頭を抱く必要はありません。
- 1. メインjava.lang.RuntimeException:アクティビティを開始できませんComponentInfo
- 2. アンドロイド:PendingIntent.getService対Context.startServiceでサービス開始
- 3. CoreDataとNSManagedObject Context - プライベート対メイン
- 4. AndroidRuntime:致命的例外:メインjava.lang.RuntimeException:アクティビティを開始できませんComponentInfo
- 5. メイン関数が開始される前にセグメンテーションフォールト11(おそらくstruct内)
- 6. メイン操作をブロック/待機せずに新しいスレッドを開始
- 7. コールNSOperation
- 8. NSOperation finished
- 9. NSOperationからダウンロードが開始されたときにNSURLDownloadDelegateが呼び出されない
- 10. Win APIの絶対的な開始 - どこから始めるのですか?
- 11. ブラックベリーのメイン画面内に新しいメイン画面を開く
- 12. 絶対位置divがメインのコンテンツ
- 13. Woocommerce Subscriptionを開始する開始日
- 14. セッション開始が '開始'でない
- 15. SPD 2010のワークフローの開始/開始
- 16. 単体テストNSOperation?
- 17. NSOperation in global queue
- 18. FMDatabaseとNSOperation
- 19. コアデータとNSOperation
- 20. NSOperation with repeat option
- 21. NSTimer in NSOperationサブクラス
- 22. ASINetworkQueue NSOperationブロッキングメインスレッド内
- 23. モーダルNSAlert from NSOperation
- 24. NSOperationとCoreDataスレッディング
- 25. NSFetchedResultsControllerとNSOperation
- 26. iPhone開発開始
- 27. 特定のスクリプト行で対話モードを開始する
- 28. 取引を休止/ロールバックを開始/(もsession.clear対をコミット)
- 29. 春の相対パスファイルインポートの開始パスは何ですか
- 30. Windows IIS Dockerコンテナで対話セッションを開始できません
メインフィニッシュ後に「isFinished」がtrueに設定されていると思います。それは理由の1つかもしれません。 – Anshu
この回答は、「同時」とは「バックグラウンドで実行される」という意味です。これはNSOperationでの「同時」の意味ではありません。並行操作と非並行操作の両方をバックグラウンドで実行できます(マルチスレッド違反のため「微妙なエラー」があります)。キューなしで実行すると、どちらかが完全に同期する可能性があります。キューを使用して実行した場合(10.6以降)、両方ともバックグラウンドスレッドで実行されます。デフォルトの 'start'は' main'を呼び出します。並行操作は 'start'をオーバーライドする必要があります(デフォルトでは非並行動作となります)。それが違いの源です。 –