問題タブ [nsoperation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
279 参照

iphone - iPhone OS 3.1 の NSOperationQueue が、長い間キャンセルされた (および解放された) 操作を保持するのはなぜですか?

NSOperationsWeb API へのサービス呼び出しを管理するために使用するアプリがあります (呼び出しは、Jon Wight の touchcode の CURLOperation に基づいています)。

マップ ビューの中心が大幅に変化したときに、マップの位置をダウンロードする特定の呼び出しがあります。これらはすぐにスタックする可能性があるため、マップを移動すると、古い操作を積極的にキャンセルしようとします. 4.0でうまく機能します。

ただし、3.1 では、特定のケースでは、オペレーション キューがキャンセルされた (および解放された) オペレーションを保持し、キューにあるはずの場所に到達したときにクラッシュを引き起こすようです。

これがイラストです。

キュー内の比較的重いサービス コールから始めます。

  1. MyLongRunningOp 0x1

ユーザーがマップに移動します。キューは次のようになります。

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

マップを移動すると、MyMapOp 0x2 がキャンセルされ、MyMapOp 0x3 が追加されます。

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2キューから削除されたため、リリースされました。これMyLongRunningOp 0x1で終了。isFinished キーを on に設定するための KVO コールバックでMyLongRunningOpは、操作キューが通知を処理し、MyMapOp 0x2いくつかの に追加しようとしていることがわかりますNSArray。当然、NSZombies有効にすると、

NSOperationQueueキャンセル/解放された操作へのポインタに何らかの形でぶら下がっており、前の操作が終了した後にそれをアクティブにしようとしているようです。

4.0 でこの動作を再現できなかったので、3.1 のバグだと思います。

私が知る限り、唯一の回避策は操作をキャンセルしないことです。これにより、ネットワークが不安定になったときに次善のエクスペリエンスが得られます。

他の誰かがこれを経験しましたか?何か案は?

0 投票する
1 に答える
2950 参照

iphone - iPhone / iOS popViewControllerAnimated 画面を更新しない

画面が適切に更新されず、ポップされたビューが表示されたままになっているが、明らかに割り当てが解除さ.navigationController popViewControllerAnimated:YESれている場所から呼び出すと、奇妙な問題が発生します。NSOperation

sqlite詳細: ローカルデータベースにアクセスするリスト ビューがあります。レコードをタップすると、そのレコードの詳細ビューが表示され、(メイン スレッドで) 非同期の NSOperation が開始され、XML バックエンド データベースをチェックして、そのレコードがまだデータベースで使用可能かどうかが確認されます。アーキテクチャ上の理由から、この操作はリスト ビューでは実行できません。詳細ビューで実行する必要があります。最後の同期以降にレコードが削除された場合、レコードが削除されたことをユーザーに通知popViewControllerAnimatedし、共有アプリのデリゲートで を呼び出します。理想的には、これにより現在の詳細ビューがポップされ、前のリスト ビューに戻ります。

エラー: 適切なビューが実際にはメモリにポップされていますが (割り当てが解除されています)、まだ画面に表示されています。ナビゲーション バーは空白ですが、「戻る」ボタンがあるべき場所をクリックすると、リスト ビューの前に開始画面に移動します。つまり、少なくともナビゲーション バーは本来あるべき場所を理解しています。タイトルまたは戻るボタンが正しく表示されない場合。主な問題は、詳細ビューがまだ表示されていて操作できるため、アプリケーションがクラッシュすることです。たとえば、詳細ビューにもデータが表示され、ユーザーがテーブルを下にスクロールすると、「メッセージが割り当て解除されたインスタンスに送信されましたUITableView」という例外がスローされます。-[xAccountDetailController tableView:cellForRowAtIndexPath:]:

これにより、呼び出しによって詳細コントローラーの割り当てが適切に解除されたと思われますが、ビューコントローラーがナビゲーションコントローラーからポップされたとしてもpopViewControllerAnimated、テーブルが実際に を呼び出す場合、明らかに何かがまだメモリに存在します。cellForRowAtIndexPath

詳細ビュー (バックエンドで削除されていないレコードの場合) で戻るボタンを手動で押すと、完全に機能します。

回避策: NSOperation に詳細ビュー コントローラーへの参照を渡すときに、popViewControllerAnimatedそのビューの navigationController プロパティから直接、および共有アプリ デリゲートから を呼び出そうとしました。また、2 つのビューをポップして、リスト ビューを navigationController に再プッシュしようとしましたが、ルート ビュー コントローラーとリスト ビュー コントローラーがナビゲーション バーに同時に存在するように見える (タイトルが互いに上書きされる) さらに厄介なインターフェイス効果が発生します。存在しないのではなく)。NSOperation に存在する詳細ビュー コントローラーへの参照を nil に設定しようとしましたが、何もしません。ポップする前に a を呼び出してみまし[detailView release]たが、予想どおり、リリース前の保持カウントが 1 しかなかったため、ポップで失敗します。私'popToViewControllerそしてpopToRootViewController、何も機能していないようです。古いビューは常にそこにあり、ナビゲーション バーは何かを実行しているように見える唯一のインターフェイス要素であり、それでも正しく表示されません。ビューが表示されたまま(ポップなし)になってもかまわないので、テーブルのリロードも試みましたが、データをクリアしたいだけですが、何らかの理由でテーブルが reloadData しません。

考え: NSOperation を実行している operationQueue は問題の詳細ビューのプロパティであるため、詳細ビューの dealloc で cancelAllOperations を実行し、operationQueue への参照を nil に設定するようにしました。また、他のオブジェクトのそのビューへのすべての参照が nil に設定されていることを確認しようとしました。詳細ビューのボタンから直接呼び出すpopViewControllerAnimatedことは完全に機能するため、ポップしたい詳細ビューのプロパティである NSOperationQueue で実行されている NSOperation からそのメソッドを呼び出しているという事実に違いありません。どこかの参照がそのビューを部分的に維持しているに違いありませんが、ポップが呼び出されたときにまだビューを参照しているものを見つけることができないようです。

ここに投稿するにはあまりにも多くの場所にコードが多すぎます。

何かご意見は?

長い質問で申し訳ありませんが、よろしくお願いします。

グレッグ


編集 1: 新しい UIViewController を使用して、NSOperation の外部でこの問題を簡単に再現できます。

メソッドでは、次のtableView:didSelectRowAtIndexPathように呼び出します。

vc では、popView メソッド:

これは保持カウントや NSOperation とは関係ないと思います。この方法でビューをポップすることで根本的に間違ったことをしていますか?

0 投票する
1 に答える
383 参照

iphone - NSOperation(s)はiOS3デバイスでのみリークします

CoreDataのインポートを処理するNSOperationsサブクラスがいくつかあります。メインスレッド以外の問題のほとんどにチェックを入れたと思います

  • mainメソッドで独自の自動解放プールを作成します
  • NSManagedObjectContext操作ごとにを作成します

これらの操作はNSOperationQueueにロードされ、同時操作の最大数は1に設定されます。

コードはiOS4.0.1で完全に機能しますが、iOS 3.1.3デバイスでは、次のような多くのログメッセージが表示されます

NSOperationサブクラスのメインメソッド

__lookup:inContext:方法_

他のほとんどのメソッドはメソッドをインスタンス化します。つまりthreadContext、メソッドに似てい__lookup:inContext:ます。インスタンスメソッドの自動解放プールを作成しないことは知っていますが、自動解放がどのように機能するかについての私の理解によれば、これらのメソッドがメインメソッド内でのみ呼び出される限り、NSAutoreleasePool作成された後、最も外側のプール使用すべきです。NSManagedObjectContextなどのオブジェクトを怠惰に作成し、ほとんどの場合、startメソッドを使用しません

0 投票する
1 に答える
199 参照

multithreading - アプリの応答性を高めるにはどうすればよいですか?

バックグラウンド

これは私の前の質問と同じ背景ですが、Outline ビューにはフェッチ述語がありません。

  • NSOutlineViewTrainingGroup エンティティを示すがあります。

  • NSOutlineViewにバインドされていますNSTreeController

  • NSTreeController では、「選択を保持する」にチェックを入れ、「挿入されたオブジェクトを選択する」のチェックを外しました。

  • 各 TrainingGroup は、ローカル マシン上のフォルダーを表します。

  • 各 TrainingGroup をプロジェクトに割り当てることができます。プロジェクトは、そのグループのすべての子孫に伝播する必要があります。

  • プロジェクト列は、各トレーニング グループのプロジェクト プロパティにバインドされます。

  • このビューには多くのデータがあります。各エントリにはエントリがあるため、1 つのトレーニング ビューの下に合計で最大 15000 の子孫が存在する可能性があります。

アウトライン表示

ツリーは次のようになります。

プロジェクト割り当て時

  • プロジェクトが編集されると、すべての子への割り当てがNSOperationバックグラウンド スレッドのサブクラスで行われるため、ユーザーは自由に他の選択を行ったり、すべての子孫が処理されている間に移動したりできます。

  • 操作が完了したら、mergeChangesFromContextDidSaveNotification:メインのマネージド オブジェクト コンテキストでメソッドを実行します。

    mainContext = [[NSApp delegate] managedObjectContext]; [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES];

  • 機能的には、これは正常に機能します。コンテキストがメインにマージされると、すべての子孫がプロジェクトに割り当てられます。

問題

  • マージ時にNSOutlineView、メイン コンテキストにバインドされている がフリーズし、マージが完了するまでに数秒かかる場合があります。

  • このフリーズを減らすために、いくつかの小さな操作に割り当てるグループをまとめました。

このバッチ処理されたバックグラウンド操作のアプローチには、次の 3 つの問題があります。

  1. インターフェイスが一瞬応答しなくなります。これは大したことではありませんが、インターフェイスで予測できない小さな一時停止が発生することを意味します。

  2. アウトライン ビューは、再びマージされた各バッチを更新します。

  3. 割り当てられたグループの下の一部のプロジェクトは空白のままです。オブジェクトはプロジェクトに割り当てられていますが、アウトライン ビューはプロジェクトを適切に更新していません。おそらく、メインスレッドがマージによって中断されるためです。

私が記録したスクリーンキャストでこれらの問題を確認できます。

http://screenr.com/Fk4

オルタナティブ

各操作からの変更を、バックグラウンド スレッドで実行されている管理オブジェクト コンテキストにマージできます。メインスレッドにメッセージを送信して、変更された最上位グループ内のすべてのオブジェクトを更新することができます。

これにより、上記の問題 1 と 3 は解消されるかもしれませんが、2 の問題は依然として残ると思います。

私の質問

これを行うより良い方法はありますか?

これを行う方法を作り直す前に(これがどのように機能するかをすでに変更しました)、より良い方法があるかどうか、またはこのアプローチに私が知らない欠点があるかどうかを知りたいです。

代替案についての提案を事前に感謝します。

0 投票する
3 に答える
2511 参照

iphone - NSOperations を使用した iOS アプリのアーキテクチャ

2 か月前、私は新しい iPhone アプリケーションの作成を開始しました。このため、ユーザー認証、ユーザー プロファイル、フレンドシップ システム、メディア処理、メッセージングなどの必要な機能を多数持つことができる、一般的な RESTFul Web サービスを作成しました。システムなど。私の考えでは、将来の iPhone アプリケーションでこの Web サービスを再利用するユースケースがいくつかあります。

このような心構えで、メディア (画像、ビデオ、サウンド) のセットアップと処理、Web サービスとの通信、解析とマッピングなどのすべての重労働を処理する、このアプリケーション (および将来のすべてのアプリケーション) 用の静的ライブラリを作成することにしました。結果の処理、CoreData の処理など。

私のアプリケーションでは、多くの並列タスクが実行されているシナリオがあります (最悪の場合)。たとえば、ユーザーが現在自分のプロフィール写真を変更しているときに、アプリケーションがユーザーの場所を (バックグラウンドで) サーバーに送信し、新しいプッシュ通知が送信されます。受け取った。

そこで、各論理操作 (SendUserLocation や GetCurrentFriendList など) を NSOperation にカプセル化し、それらを serviceQueue (NSOperationQueue) に追加することにしました。

各操作は、操作が Web サービスから結果を正常に取得し、すぐに処理する必要がある場合にサブタスクを生成できます。

代替テキスト

典型的な ServiceManager メソッドは次のようになります

各操作、(サーバーへの) 要求、および subTask は、GUID を notificationName として使用して、処理が完了したときに親オブジェクトに通知します。操作のすべてが完了すると、ユーザー インターフェイスに通知が返されます。

とはいえ、サブタスクを追加および削除するためのコードは次のようになります

あとは、GUI で serviceManager を呼び出して、次のような特定の操作を開始するだけです。

オブザーバーを登録したい場合は、次のようにオブザーバー オブジェクトとセレクターを渡すだけです。

最後になりましたが、私の質問: 「アーキテクチャ」は非常にうまく動作し、安定していますが、実行する価値はありますか? オーバーヘッドが多すぎますか? それは理にかなっていますか?個人的には、並行操作をどのように実装していますか?

ベスト・ヘンリック

PS私の質問を自由に編集し、質問をして(コメントとして)、この考えの名前を呼んでください。

基本的に私は英語のネイティブスピーカーではないので、説明するのに本当に苦労しました. 誤解しないでください。私は、この投稿を何らかの形で自慢するために書いたわけではありません。私がしたいのは学ぶことだけです(そして、より高度なiPhone / Objective Cの質問を書くことかもしれません)

0 投票する
6 に答える
47736 参照

iphone - NSOperationを並行してキャンセルできるようにサブクラス化する

並行してサブクラス化する方法とNSOperationキャンセルをサポートする方法についての適切なドキュメントを見つけることができません。Appleのドキュメントを読みましたが、「公式」の例を見つけることができません。

これが私のソースコードです:

私が見つけた例では、performSelectorOnMainThread:が使用されている理由がわかりません。それは私の操作が同時に実行されるのを妨げるでしょう。

また、その行をコメントアウトすると、操作が同時に実行されます。ただし、isCancelledを呼び出してもフラグは変更されませんcancelAllOperations

0 投票する
5 に答える
14534 参照

iphone - iOS4デバイスでバックグラウンドで大量のデータを送信するためのベストプラクティス?

サーバーに(POSTを使用して)データを送信する必要があるアプリがあります。この機能は、NavigationControllerサブコントローラーの1つにある必要があり、ユーザーはこのコントローラーから離れたり、アプリを閉じたりできる必要があります(iPhone4 / iOS4のみがサポートされます)。スレッド/NSOperationsを使用するか、または/および既存の非同期メソッドを使用してデータを送信する必要がありますか?これを実装するためのアイデア/ベストプラクティスはありますか?

0 投票する
3 に答える
1194 参照

iphone - NSOperation同期の問題

iPhoneアプリの操作を同期する方法を見つけるのに苦労しています。私は3つの主要なNSOperationを持っています。

3つの操作が順番に正しく開始されていることがわかります。ただし、ご想像のとおり、最初の操作ではUIViewを作成して上部にアタッチし、最後の操作では削除する必要があります。

グラフィカルに言えば、操作は画面上で一度に発生します。そのため、スピナーが画面に表示されているときにテーブルが既に読み込まれていることや、その他の奇妙な同期されていないことがわかります。

グラフィック側の変更はメインスレッドで発生することを理解しました。だから私は、コードを変更して、本来の機能を実行するにはどうすればよいかを尋ねています。スピナーを作成し、データをロードし、スピナーを削除しますか?グラフィック操作とデータ操作を分離する一般的な方法はありますか?たとえば、2つの異なる操作を作成します。

ありがとう

0 投票する
1 に答える
2253 参照

multithreading - NSOperation サブクラスで Core Data 関係を変更すると、アプリがクラッシュするのはなぜですか?

バックグラウンド

次のオブジェクトのツリーがあります。

  • ユーザーはグループをプロジェクトに割り当てることができます。すべての子孫がそのプロジェクトに設定されます。

  • これによりメインスレッドがロックされるため、NSOperations を使用しています。

  • 私はこれを行うためにAppleが承認した方法を使用してNSManagedObjectContextDidSaveNotificationおり、メインのコンテキストを監視してマージしています。

問題

保存が次のエラーで失敗しています:

Failed to process pending changes before save. The context is still dirty after 100 attempts. Typically this recursive dirtying is caused by a bad validation method, -willSave, or notification handler.

私が試したこと

アプリの複雑さをすべて取り除き、考えられる最も単純なプロジェクトを作成しました。そして、エラーはまだ発生します。私はもう試した:

  • キューの操作の最大数を 1 または 10 に設定します。

  • NSOperationrefreshObject:mergeChanges:サブクラスのいくつかのポイントでの呼び出し。

  • 管理対象オブジェクト コンテキストにマージ ポリシーを設定します。

  • 構築して分析します。それは空になります。

私の質問

アプリをクラッシュさせずに NSOperation で関係を設定するにはどうすればよいですか? これは Core Data の制限ではないのでしょうか? それをできる?

コード

私のプロジェクトをダウンロードしてください: http://synapticmishap.co.uk/CDMTTest1.zip

メインコントローラー

リレーションシップ操作を行う

データ・モデル

データ・モデル

更新 1

私はもう少し実験しましたが、マージがなくても例外がスローされます。リレーションシップを変更した後、別のスレッドに管理オブジェクト コンテキストを保存するだけで十分です。

アプリ デリゲートと共有の永続ストア コーディネーターがあります。データ ストアと同じ URL を持つスレッド用に別の NSPersistentStoreCoordinator を作成しようとしましたが、Core Data が文句を言います。

スレッドのコーディネーターを作成する方法について提案したいと思います。コア データ ドキュメントには、それを行う方法があることがほのめかされていますが、方法がわかりません。

0 投票する
1 に答える
2159 参照

iphone - NSOperationQueue が iOS 4.0 で正しく動作しないのはなぜですか?

以前は iPhone OS 3.0 の iPhone アプリで NSOperationQueue を使用していましたが、iOS 4.0 ではコードが正しく機能しません。一度だけ正しく実行され、その後のすべての呼び出しでは機能しません。iOS 4.0 の NSOperationQueue に変更はありますか?

関連するコードは次のとおりです。