Reputation: 514
I'm working on a project where I need to work with large arrays, and by using UnsafeMutablePointers, I get a threefold speed increase over using the regular array methods. However, I believe the copy on write behavior is causing me to change instances that I do not want to be affected. For example, in the following code, I want to update the values in copyArray, but leave the original values in anArray.
import Foundation
func increaseWithPointers(_ arr: inout [Int]) {
let count = arr.count
let ptr = UnsafeMutablePointer(mutating: &arr)
for i in 0..<count {
ptr[i] = ptr[i] + 1
}
}
var anArray = [1,2,3,4,5]
var copyArray = anArray
increaseWithPointers(©Array)
print(anArray)
Executing this code prints [2,3,4,5,6].
I can get around this by declaring copyArray as follows:
var copyArray = [Int](repeating: 0, count: 5)
for i in 0..<5 {
copyArray[i] = anArray[i]
}
However, this requires writing each value twice: to zero, then to the intended value. Is there a way to efficiently guarantee a copy of an array?
Upvotes: 1
Views: 376
Reputation: 385510
I can reproduce your problem using Xcode 9 beta 3, but not using Xcode 8.3.3. I suggest you file a Swift bug report.
This fixes the problem:
import Foundation
func increaseWithPointers(_ arr: inout [Int]) {
arr.withUnsafeMutableBufferPointer { (buffer) in
for i in buffer.indices {
buffer[i] += 1
}
}
}
var anArray = [1,2,3,4,5]
var copyArray = anArray
increaseWithPointers(©Array)
print(anArray)
Upvotes: 1