質問

私は、ウェブからデータを引き出し、それらを解析し、検索インタフェースで結果をコンパイルしたアプリケーションを持っています。データは、共依存しないので、複数のフェッチを実行するマルチスレッドアプリケーションにセンスを行い、同時に解析します。私は、この機能を実行するために書かれている検索にNSInvocationOperationを使用してオブジェクトを解析します。

私は次のメソッドを有するコントローラ・オブジェクトに

-(void) searchAndParseAsynchronously { 
 NSPort *serverPort = [NSMachPort port];
 NSConnection *serverConnection = [NSConnection connectionWithReceivePort:serverPort sendPort:serverPort];
 [serverConnection setRootObject:self];
 for (NSURL *urlToProcess in self.urlsToFetch)
 {
  BaseSearchParser *searcherForURL = [BaseSearchParser newSearchParserWithParameters:self.searchParams];
  searcherForURL.urlToDocument = urlToDocument;

  SearchThreader *searchThreader = [SearchThreader new];
  searchThreader.threadConnection = comConnection;
  searchThreader.targetSchema = searcherForURL; 
  NSInvocationOperation *threaderOperation = [[NSInvocationOperation alloc] initWithTarget:searchThreader 
                                                                                        selector:@selector(executeSearchParse) 
                                                                                          object:nil];
  [self.operationQueue addOperation:threaderOperation];
 }
}

アプリケーションは、私が主に危険なスレッドである収集したコアデータに依存しています。私は、各探索/解析操作(及びコントローラ用に1つ)に対して異なるNSManagedObjectContextを有し、操作のみまたはプロキシオブジェクト間NSManagedObjectIdを渡す。

の操作はNSConnectionオブジェクトを介してバックそのコントローラに完了解析結果を伝えます。コントローラはNSMachPortオブジェクトを使用してNSConnectionを構築し、ルートオブジェクトとしての地位を設定し、NSInvocationOperationsのターゲットのそれぞれに同じNSConnectionオブジェクトを返します。コントローラは、次に、自身のNSOperationQueueにおける実行のためNSInvocationOperationをエンキューします。

私は次のメソッドを持っている検索通しオブジェクトでます:

-(void) executeSearchAndParse
{ 
 id parentServer = [threadConnection rootProxy];
 [parentServer setProtocolForProxy:@protocol(SearchParseProtocol)];

 NSArray *importResults = [targetSchema generatedDataSetIds];

 [parentServer schemaFinished:targetSchema];
 [parentServer addSearchResults:importResults];
}

私は<のhref =「http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html」のrel与えられた一般的なスレッド間通信のアップルの例に従っていると信じて= "nofollowをnoreferrer">ここを。

期待とコントローラオブジェクトの準備ができるまで、ピックアップを待つようNSConnection rootProxyからの通知は、メインスレッドで実行ループに掲載されます。

私はほとんどの時間は、これが見事に動作することを言わなければなりません。時々メッセージがのrootProxyオブジェクトを呼び出しているNSInvocationOperationオブジェクトと同じスレッドでコントローラオブジェクトのにそれを作るためしかし、私のテストケースのいくつかでそれが急停止に粉砕するコアデータが発生します。

私は(ちょうど時々)検索/解析操作は時々、完全な、そして十分に確認されたときに送信されるメッセージには、コントローラで実行中のスレッドをデバッガポイントを配置したされ、のないの主なもの。誰もが、これが発生する可能性のある理由として考えを持っていますか?または、スレッド間の非同期通信を構築するための簡単な方法はありますか?またはコアデータのための私のアプローチは完全にオフ元気でしょうか?

事前に感謝します!

役に立ちましたか?

解決

私はあなたのアプローチに何か問題が表示されていないと前に同様の方法でNSConnectionを使用していました。私が見る唯一の私の事は、私はだけではなく、明示的にNSPortを使用してのNSMachPortを使用したことである。

  

あるいは、スレッド間の非同期通信を構築するための簡単な方法がありますか?

私はAppleがもはやスレッド間通信のためのditributedオブジェクトを推進しているとは思いません。 IIRC、この推測は、ほとんどが実際にスレッド間通信のためのDOを促進するが、私が言及見てきた文書に基づいている削除または編集されているからです。

NSObjectの上のメソッドを使用する方がはるかに簡単です:

この私も、スレッド関連のperformSelectorと思います

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait

(第2の一方は上で10.5からのみ入手可能である)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top