2016-04-11 8 views
1

Ich brauche in meinem appBAD_EXEC NSOperationQueue mit Ersten

asynchrone Aufgaben ausführen

Ich habe den folgenden Code:

- (NSDictionary *)parallelSendSync:(NSDictionary *)requests { 

    NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; 
    for (NSString *key in [requests allKeys]) { 
     [_parallelSendQueue addOperationWithBlock:^{ 
      NSDictionary *sendResult = [self send:requests[key] :nil]; 
      [responseDict setObject:sendResult forKey:key]; //this line sometimes throws BAD_EXEC 
     }]; 

    } 
    [_parallelSendQueue waitUntilAllOperationsAreFinished]; 

    return responseDict.copy; 

} 

_parallelSendQueue akzeptiert maximal 5 gleichzeitige Operationen

leider nur einen Teil der Werke Zeit, manchmal funktioniert es OK, und manchmal wirft es BAD_EXEC

was könnte der Grund für die schlechte Exec sein?

+1

Zeigen Sie das vollständige Crashprotokoll an. – trojanfoe

+0

leider bleibt es stecken, und liefert mir kein Crash-Log –

+0

Dieser Code sollte nicht funktionieren, ich erwarte, dass der Absturz tatsächlich außerhalb von diesem ist und Sie die NSDictionary zurückgeben, die möglicherweise Zeug haben, wie es async gefüllt wird aber du gibst es sofort zurück? Eine bessere Lösung wäre es, NSOperation (sehr einfach) abzuleiten und "main" zu überschreiben und einen Completion-Block zu übergeben, der ein NSDic zurückgibt. – SeanLintern88

Antwort

2

Das Problem besteht darin, dass mehrere Threads dasselbe Objekt verwenden, was zu einer Speicherbeschädigung für nicht Thread-sichere Objekte führen kann.

Sie haben zwei Möglichkeiten:

  • Sperren Sie das Objekt von mehreren Threads verwendet werden oder einer parallelen Warteschlange, so dass nur eine Operation es zu einer Zeit
  • Versand nach einer bestimmten Thread oder serielle Warteschlange ändern kann, die besitzt das gemeinsame Objekt und von dort ändern (aber Vorsicht, wenn Sie auf den gleichen Thread versenden, die derzeit waitUntilAllOperationsAreFinished das Programm blockiert wird ruft)

ich denke, die beste Lösung in Ihrem Fall blockiert:

- (NSDictionary *)parallelSendSync:(NSDictionary *)requests { 

    NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; 
    for (NSString *key in [requests allKeys]) { 
     [_parallelSendQueue addOperationWithBlock:^{ 
      NSDictionary *sendResult = [self send:requests[key] :nil]; 
      // synchronized locks the object so there is no memory corruption 
      @synchronized(responseDict) { 
       [responseDict setObject:sendResult forKey:key]; 
      } 
     }]; 
    } 
    [_parallelSendQueue waitUntilAllOperationsAreFinished]; 

    return responseDict.copy; 

} 
2

Wenn Sie fünf Aufgaben parallel ausführen, die versuchen, das Wörterbuch zu ändern, dann ist ein Absturz zu erwarten. Das Ändern von responseDict muss mit @synchronized erfolgen. NSMutableDictionary ist nicht threadsicher.

Verwandte Themen