2016-05-04 190 views
2

我有2个函数将数据追加到数组和一个函数来处理它。我使用dispatch_barrier_sync来防止其他函数在处理它时更改数据。dispatch_barrier_sync上的数组损坏

内追加功能:

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

处理功能内:

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)) 
      } 
     } 

在上述功能,bufferVector是NSData的([NSData的])的阵列

功能工作正常,它不久之后,似乎阵列内的NSData已损坏,并且我收到了EXC_BAD_ACCESS

这是什么节目,当我尝试从调试程序来查看bufferVector内容

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

我可以说,它已损坏,因为NSData的显示内存地址,而不是在字节长度

干杯

+0

与这个问题无关:使用'weak self'然后使用'self!'是没有意义的。如果你断言'self'在这个块完成之前永远不会消失,那么使用'unowned self'。如果你想确保'self'在这个块完成之前不能消失(这是你几乎可以肯定的意思),那么就使用默认的(strong)'self'。如果你的意思是“如果在这个运行之前'自我'发生了消失,忽略它',使用'弱'和'自我'。你目前的代码强加“弱”的成本,但没有获得任何安全性。 –

+0

谢谢,我会改变我的逻辑。我可能会用强而不是弱。 – Adrian

+0

@RobNapier你觉得用strongSelf = self来使用守卫怎么样? –

回答

2

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

您指定的队列应该是您使用dispatch_queue_create函数创建的并发队列。如果传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为与dispatch_sync函数相同。

1

添加到罗布的回答,您可以创建一个队列,你可以访问或传递给任一方法:

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) 

然后使用它像:

// Getting elements 
dispatch_sync(newConcurrentQueue) { 

} 

// Setting elements 
dispatch_barrier_async(newConcurrentQueue) { 

} 

相关评论关于你的问题,我个人喜欢早期的回归模式,并且防止自己被消失:

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

    guard let strongSelf = self else { 
    return 
    } 
}