2016-05-04 10 views
2

Ich habe 2 Funktion, die Daten an Array anhängen und eine Funktion, um es zu verarbeiten. Ich verwende dispatch_barrier_sync, um zu verhindern, dass andere Funktionen die Daten ändern, während ich sie verarbeite.Array beschädigt auf dispatch_barrier_sync

innen append Funktion:

autoreleasepool { 
      dispatch_barrier_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { [weak self]() -> Void in    
       self?.bufferVector_.append(data) 
      } 
     } 

innen Prozessfunktion:

autoreleasepool { 
      dispatch_barrier_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { [weak self] in 
       let len = self!.bufferVector_.count 

       if len > numToExtract { 

        isMoreInBuffer = true 
       } 

       for bufferData in self!.bufferVector_ { 

        datas.append(bufferData) 

        cnt += 1 

        if cnt == numToExtract { 

         break; 
        } 
       } 

       self!.bufferVector_.removeRange(Range(start: 0, end: cnt)) 
      } 
     } 

In obiger Funktion ist bufferVector Array von NSData ([NSData])

Die feinen Funktion der Arbeit, es Nach einer Weile scheint es, dass die NSData innerhalb des Arrays beschädigt ist und ich EXC_BAD_ACCESS

erhalten

363.210 Dies ist, was Show ist, wenn ich versuche bufferVector Inhalte von Debugger

bufferVector_ = ([NSData]) 8 values 
    [0] = (NSData) 98 bytes 
    [1] = (NSData) 0x16595320 
    [2] = (NSData) 52 bytes 
    [3] = (NSData) 52 bytes 

Ich kann sagen, dass es beschädigt ist, weil die NSData Show Speicheradresse statt auf Bytes Länge

Prost

+0

Ohne Bezug auf die Frage: Es macht keinen Sinn, "schwaches Selbst" zu verwenden und dann "selbst!" Zu verwenden. Wenn Sie behaupten, dass "self" niemals verschwinden kann, bevor dieser Block abgeschlossen ist, verwenden Sie "unowned self". Wenn Sie sicherstellen wollen, dass "self" nicht verschwinden kann, bevor dieser Block abgeschlossen ist (was Sie hier fast sicher meinen), verwenden Sie einfach das Standard (strong) 'self'. Wenn du meinst "wenn" self "verschwindet, bevor das läuft, ignoriere es," benutze 'weak' und' self? '. Ihr derzeitiger Code verursacht die Kosten von "schwach", ohne dass er von seiner Sicherheit profitiert. –

+0

Danke, ich werde meine Logik diesbezüglich ändern. Ich werde wahrscheinlich mit starken anstelle von schwachen gehen. – Adrian

+0

@RobNapier was denkst du über die Verwendung einer Wache mit lost strongSelf = self? –

Antwort

2

You can't apply a barrier to a global queue:

anzuzeigen

Die von Ihnen angegebene Warteschlange sollte eine gleichzeitige Warteschlange sein, die Sie mit der Funktion dispatch_queue_create selbst erstellen. Wenn die Warteschlange, die Sie an diese Funktion übergeben, eine serielle Warteschlange oder eine der globalen gleichzeitigen Warteschlangen ist, verhält sich diese Funktion wie die Funktion dispatch_sync.

1

Hinzufügen zu Robs Antwort können Sie eine Warteschlange erstellen, können Sie entweder den Zugriff oder entweder Methode zu übergeben:

let qosClassUserInit    = QOS_CLASS_USER_INITIATED 
let newConcurrentQueueAttributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, qosClassUserInit, 0) 
let newConcurrentQueue    = dispatch_queue_create("SynchronizedArrayAccess", newConcurrentQueueAttributes) 

Dann nutzen Sie es mögen:

// Getting elements 
dispatch_sync(newConcurrentQueue) { 

} 

// Setting elements 
dispatch_barrier_async(newConcurrentQueue) { 

} 

Im Zusammenhang mit dem Kommentar auf Ihrer Frage, ich persönlich mag die frühe Rückkehr Muster und Schutz gegen Selbstsein gegangen:

someBlock { [weak self]() -> Void in 

    guard let strongSelf = self else { 
    return 
    } 
}