4

Array最後の要素をポップしてすぐに別の配列に追加できる拡張機能を作成しました。

extension Array {

    mutating func popLast(to otherArray: inout [Element]) -> Element? {
        guard self.count > 0 else { return nil }
        return otherArray.appendAndReturn(self.popLast()!)
    }

    mutating func appendAndReturn(_ element: Element) -> Element {
        self.append(element)
        return element
    }

}

遊び場のこの簡単な例は魅力のように機能します:

var newNumbers = [1,2,3,4,5,6,7,8,9]
var usedNumbers: [Int] = []

newNumbers.popLast(to: &usedNumbers)
print(usedNumbers) // [9]

for _ in newNumbers {
    newNumbers.popLast(to: &usedNumbers)
}

print(usedNumbers) // [9, 8, 7, 6, 5, 4, 3, 2, 1]

しかし、構造体 (警告の後のコード) 内で拡張機能を使用すると、次の警告が表示されます。

パラメータ 'self' への同時アクセスですが、変更には排他的アクセスが必要です。ローカル変数へのコピーを検討する

struct Test {

    var newNumbers = [1,2,3,4,5,6,7,8,9]
    var usedNumbers: [Int] = []

    mutating func getNewNumber() -> Int? {
        return newNumbers.popLast(to: &usedNumbers)
    }

}

これは単なる警告であり、私のアプリは予想どおりの動作で問題なく動作しますが、本当に危険があるのか​​知りたいです。SE-0176を見ると、警告の目的を理解できます。これを使用して、追加先の同じ配列から最後の要素をポップすると、コピーオンライトがそれを台無しにする可能性があるためです。そして、それは構造体に関連していると思います。しかし、同じ構造体内の 2 つの異なる配列で使用しても、危険はありません。潜在的な問題を回避する拡張機能を作成する方法はありますか?

4

1 に答える 1