Frage

Ich habe eine Anwendung, die Daten aus dem Netz zieht, analysiert sie und stellt die Ergebnisse in einer Suchoberfläche. Da die Daten nicht co-abhängig sind, es sinnvoll, auf die Anwendung mehrfädigen mehrere Fetches auszuführen und gleichzeitig parst. Ich benutze NSInvocationOperation auf der Suche und analysiere Objekt, das ich geschrieben habe, um diese Funktion auszuführen.

In dem Controller-Objekt ich die folgende Methode habe:

-(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];
 }
}

Die Anwendung basiert auf Core Data, die ich gesammelt habe, ist meist unsicher fädeln. Ich habe eine andere NSManagedObjectContext für jeden Suche / Parse-Betrieb (und einem für den Controller), und nur die NSManagedObjectId zwischen Operationen oder Proxy-Objekten übergeben.

Die Operationen kommunizieren die fertigen Parse-Ergebnisse zurück an ihre Steuerung über ein NSConnection Objekt. Der Controller konstruiert der NSConnection ein NSMachPort Objekt verwendet wird, setzt sich als das Wurzelobjekt und gibt die gleiche NSConnection Objekt zu jedem der Ziele der NSInvocationOperations. Der Controller dann reiht die NSInvocationOperation für die Ausführung in einem eigenen NSOperationQueue.

Auf der Suche Einfädler Objekt, das ich die folgende Methode haben:

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

 NSArray *importResults = [targetSchema generatedDataSetIds];

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

Ich glaube, ich habe das Apple-Beispiel für generische inter-thread Kommunikation gegeben, gefolgt hier .

Ich muß sagen, dass die meisten der Zeit, dies funktioniert wunderbar: Die Meldungen von der NSConnection rootProxy werden die Laufschleife im Hauptthread geschrieben wie zur Abholung erwartet und warten, bis das Controller-Objekt ist fertig. in einige meiner Testfällen jedoch verursacht es Core Data zum Stillstand schleifen, weil manchmal die Nachrichten an das Controller-Objekt machen im selben Thread wie das NSInvocationOperation Objekt, das das rootProxy Objekt ruft .

ich einen Debugger Punkt in der Steuerung auf der Nachricht platziert habe, die gesendet wird, wenn die Suche / parsen Vorgang abgeschlossen ist, und sicher genug, manchmal (nur manchmal) der ausführende Thread ist nicht die wichtigste. Hat jemand eine Idee, warum dies geschehen könnte? Oder gibt es eine einfachere Art und Weise inter Thread asynchrone Kommunikation zu konstruieren? OR ist mein Ansatz für Core Data völlig aus dem Lot?

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Ich habe nichts falsch mit Ihrem Ansatz sehen und vor NSConnection in ähnlicher Weise verwendet habe. Die einzige ich, was ich sehe, ist, dass ich nur ausdrücklich NSPort statt mit NSMachPort verwendet.

  

Oder gibt es eine einfachere Art und Weise inter Thread asynchrone Kommunikation zu konstruieren?

Ich glaube nicht, dass Apple-mehr ditributed Objekte für inter-thread Kommunikation fördert. IIRC wird diese Vermutung meist auf Dokumentation basiert, die ich erwähnt habe gesehen, die DOs wirklich inter-thread Kommunikation fördert für die aber da wurden entfernt oder bearbeitet werden.

Ich denke auch, dass der Thread-bezogene perform: Methoden auf NSObject sind viel einfacher zu bedienen:

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

(während der zweiten von 10,5 auf nur verfügbar ist).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top