2017-12-24 7 views
0

配列に値を追加する際にconcurrentPerformエラーが発生しました。私はボタンを押します。 エラーの瞬間、myArray01には133があります。他のrun myArray01には69個の要素があります。どのようにこのエラーを削除しますか?コンソールconcurrentPerform配列に値を追加中にUnsafeMutablePointer.debugエラーが発生しました

fatal error: UnsafeMutablePointer.deinitialize with negative count 2017-12-24 11:59:53.438933+0300 ap02[7624:1873749] fatal error: UnsafeMutablePointer.deinitialize with negative count (lldb)

同様のトピックでエラー

Thread 8: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

のラインで

スウィフト:負の数とUnsafeMutablePointer.deinitialize致命的なエラー配列 Swift: UnsafeMutablePointer.deinitialize fatal error with negative count when appending to array

var myArray01 = [4444,5555] 

@IBAction func button01Pressed(_ sender: Any) { 
    self.doIt01() 
} 

func doIt01() { 
    DispatchQueue.concurrentPerform(iterations: 1000) { iter in 
     var max = 100000 
     for iterB in 0..<100000 { 
      var k = 0 
      k = k + 1 
      var half:Int = max/2 
      if (iterB == half) { 
       myArray01.append(iter) 
      } 
     } 
    } 
} 
+0

感謝Riajurラーマンを。ここからSynchronizedArray を作成するソリューション(スレッドセーフな配列を素早く作成する)はrmooneyから動作します。https://stackoverflow.com/questions/28191079/create-thread-safe-array-in-swift – userForStackExchange

答えて

1

に追加しますファンダム複数のスレッドから配列にアイテムを同時に追加するという問題があります。 Swift Arrayタイプはスレッドセーフではありません。あなたはそれとあなたの相互作用をsynchronizeする必要があります。それは並列でコードを実行している間、それがすべてになるまで現在のスレッドをブロックしないので、私はまた、バックグラウンドスレッドにconcurrentPerformを派遣ことをお勧めしたい

DispatchQueue.global().async { 
    let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".synchronization") 

    var array = [4444,5555] 

    DispatchQueue.concurrentPerform(iterations: 1000) { iter in 
     var max = 100_000 
     for iterB in 0 ..< 100_000 { 
      var k = 0 
      k = k + 1 
      var half = max/2 
      if iterB == half { 
       queue.async { 
        array.append(iter) 
       } 
      } 
     } 
    } 

    queue.async { 
     print(array) 
    } 
} 

注:たとえば、シリアルキューを使用して、それを自分で同期することができますそれらの並列ループの実行が行われます。


それとも、あなたのための同期を行い配列型を使用することができます。

DispatchQueue.global().async { 
    let array = SynchronizedArray(array: [4444,5555]) 

    DispatchQueue.concurrentPerform(iterations: 1000) { iter in 
     let max = 100_000 
     for iterB in 0 ..< 100_000 { 
      var k = 0 
      k = k + 1 
      let half = max/2 
      if iterB == half { 
       array.append(iter) 
      } 
     } 
    } 

    print(array) 
} 

// 
// SynchronizedArray.swift 
// 
// Created by Robert Ryan on 12/24/17. 
// 

import Foundation 

/// A synchronized, ordered, random-access array. 
/// 
/// This provides low-level synchronization for an array, employing the 
/// reader-writer pattern (using concurrent queue, allowing concurrent 
/// "reads" but using barrier to ensure nothing happens concurrently with 
/// respect to "writes". 
/// 
/// - Note: This may not be sufficient to achieve thread-safety, 
///   as that is often only achieved with higher-level synchronization. 
///   But for many situations, this can be sufficient. 

class SynchronizedArray<Element> { 
    private var array: Array<Element> 

    private let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".synchronization", attributes: .concurrent) 

    init(array: Array<Element> = []) { 
     self.array = array 
    } 

    /// First element in the collection. 

    var first: Element? { 
     return queue.sync { self.array.first } 
    } 

    /// Last element in the collection. 

    var last: Element? { 
     return queue.sync { self.array.last } 
    } 

    /// The number of elements in the collection. 

    var count: Int { 
     return queue.sync { self.array.count } 
    } 

    /// Inserts new element at the specified position. 
    /// 
    /// - Parameters: 
    /// - newElement: The element to be inserted. 
    /// - index: The position at which the element should be inserted. 

    func insert(_ newElement: Element, at index: Int) { 
     queue.async(flags: .barrier) { 
      self.array.insert(newElement, at: index) 
     } 
    } 

    /// Appends new element at the end of the collection. 
    /// 
    /// - Parameter newElement: The element to be appended. 

    func append(_ newElement: Element) { 
     queue.async(flags: .barrier) { 
      self.array.append(newElement) 
     } 
    } 

    /// Removes all elements from the array. 

    func removeAll() { 
     queue.async { 
      self.array.removeAll() 
     } 
    } 

    /// Remove specific element from the array. 
    /// 
    /// - Parameter index: The position of the element to be removed. 

    func remove(at index: Int) { 
     queue.async { 
      self.array.remove(at: index) 
     } 
    } 

    /// Retrieve or update the element at a particular position in the array. 
    /// 
    /// - Parameter index: The position of the element. 

    subscript(index: Int) -> Element { 
     get { 
      return queue.sync { self.array[index] } 
     } 
     set { 
      queue.async(flags: .barrier) { self.array[index] = newValue } 
     } 
    } 

    /// Perform a writer block of code asynchronously within the synchronization system for this array. 
    /// 
    /// This is used for performing updates, where no result is returned. This is the "writer" in 
    /// the "reader-writer" pattern, which performs the block asynchronously with a barrier. 
    /// 
    /// For example, the following checks to see if the array has one or more values, and if so, 
    /// remove the first item: 
    /// 
    ///  synchronizedArray.writer { array in 
    ///   if array.count > 0 { 
    ///    array.remove(at: 0) 
    ///   } 
    ///  } 
    /// 
    /// In this example, we use the `writer` method to avoid race conditions between checking 
    /// the number of items in the array and the removing of the first item. 
    /// 
    /// If you are not performing updates to the array itself or its values, it is more efficient 
    /// to use the `reader` method. 
    /// 
    /// - Parameter block: The block to be performed. This is allowed to mutate the array. This is 
    ///     run on a private synchronization queue using a background thread. 

    func writer(with block: @escaping (inout [Element]) -> Void) { 
     queue.async(flags: .barrier) { 
      block(&self.array) 
     } 
    } 

    /// Perform a "reader" block of code within the synchronization system for this array. 
    /// 
    /// This is the "reader" in the "reader-writer" pattern. This performs the read synchronously, 
    /// potentially concurrently with other "readers", but never concurrently with any "writers". 
    /// 
    /// This is used for reading and performing calculations on the array, where a whole block of 
    /// code needs to be synchronized. The block may, optionally, return a value. 
    /// This should not be used for performing updates on the array itself. To do updates, 
    /// use `writer` method. 
    /// 
    /// For example, if dealing with array of integers, you could average them with: 
    /// 
    ///  let average = synchronizedArray.reader { array -> Double in 
    ///   let count = array.count 
    ///   let sum = array.reduce(0, +) 
    ///   return Double(sum)/Double(count) 
    ///  } 
    /// 
    /// This example ensures that there is no race condition between the checking of the 
    /// number of items in the array and the calculation of the sum of the values. 
    /// 
    /// - Parameter block: The block to be performed. This is not allowed to mutate the array. 
    ///     This runs on a private synchronization queue (so if you need main queue, 
    ///     you will have to dispatch that yourself). 

    func reader<U>(block: ([Element]) -> U) -> U { 
     return queue.sync { 
      block(self.array) 
     } 
    } 

    /// Retrieve the array for use elsewhere. 
    /// 
    /// This resulting array is a copy of the underlying `Array` used by `SynchronizedArray`. 
    /// This copy will not participate in any further synchronization. 

    var value: Array<Element> { return queue.sync { self.array } } 
} 

extension SynchronizedArray: CustomStringConvertible { 
    // Use the description of the underlying array 

    var description: String { return queue.sync { self.array.description } } 
} 
関連する問題