Swift交换数组对象

Enl*_*lil 10 arrays uitableview swift

我无法在细胞重新排序上交换字符串数组

var scatola : [String] = []

override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
        swap(&scatola[fromIndexPath.row], &scatola[toIndexPath.row])
    }
Run Code Online (Sandbox Code Playgroud)

此代码抛出:inout回写计算属性'scatola'发生在多个要调用的参数中,引入无效别名

什么是正确的方法呢?

Mar*_*n R 16

更新:Swift 3.2/4(Xcode 9)开始,您必须swapAt()在集合上使用该方法

 scatola.swapAt(fromIndexPath.row, toIndexPath.row)
Run Code Online (Sandbox Code Playgroud)

因为将数组作为两个不同的 inout参数传递给同一个函数不再合法,比较SE-0173 AddMutableCollection.swapAt(_:_:)).


更新:我用Xcode 6.4再次测试了代码,问题不再发生了.它按预期编译和运行.


(旧答案:)我假设这scatola是视图控制器中的存储属性:

var scatola : [Int] = []
Run Code Online (Sandbox Code Playgroud)

您的问题似乎与https://devforums.apple.com/thread/240425中讨论的问题有关.它已经可以通过以下方式复制:

class MyClass {
    var array = [1, 2, 3]

    func foo() {
        swap(&array[0], &array[1])
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器输出:

error: inout writeback to computed property 'array' occurs in multiple arguments to call, introducing invalid aliasing
        swap(&array[0], &array[1])
                         ^~~~~~~~
note: concurrent writeback occurred here
        swap(&array[0], &array[1])
              ^~~~~~~~

我还没有掌握的讨论完全(太晚了这里的内容:),但有一个提出了"解决办法",即以纪念财产最终(所以你不能在子类中重写它):

final var scatola : [Int] = []
Run Code Online (Sandbox Code Playgroud)

我找到的另一个解决方法是获取底层数组存储的指针:

scatola.withUnsafeMutableBufferPointer { (inout ptr:UnsafeMutableBufferPointer<Int>) -> Void in
    swap(&ptr[fromIndexPath.row], &ptr[toIndexPath.row])
}
Run Code Online (Sandbox Code Playgroud)

当然,傻瓜式的解决方案就是这样

let tmp = scatola[fromIndexPath.row]
scatola[fromIndexPath.row] = scatola[toIndexPath.row]
scatola[toIndexPath.row] = tmp
Run Code Online (Sandbox Code Playgroud)


Can*_*Can 15

或者,

let f = fromIndexPath.row, t = toIndexPath.row
(scatola[f], scatola[t]) = (scatola[t], scatola[f])
Run Code Online (Sandbox Code Playgroud)