Swift交换数组对象

时间:2014-10-10 20:16:50

标签: arrays uitableview swift

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

var scatola : [String] = []

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

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

这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:16)

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

 scatola.swapAt(fromIndexPath.row, toIndexPath.row)

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


更新:我使用 Xcode 6.4 再次测试了代码,问题就出现了 不会再发生了。它按预期编译并运行。


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

var scatola : [Int] = []

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

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

    func foo() {
        swap(&array[0], &array[1])
    }
}

编译器输出:

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(以便您无法覆盖它) 在子类中):

final var scatola : [Int] = []

我发现的另一个解决方法是在底层数组存储上获取指针:

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

当然,傻瓜式解决方案只是

let tmp = scatola[fromIndexPath.row]
scatola[fromIndexPath.row] = scatola[toIndexPath.row]
scatola[toIndexPath.row] = tmp

答案 1 :(得分:15)

可替换地,

let f = fromIndexPath.row, t = toIndexPath.row
(scatola[f], scatola[t]) = (scatola[t], scatola[f])

答案 2 :(得分:0)

启动Xcode 9,你可以写:

@objc override func tableView(_ tableView: UITableView, 
                moveRowAt sourceIndexPath: IndexPath, 
                  to destinationIndexPath: IndexPath) {
    scatola.swapAt(sourceIndexPath.row, destinationIndexPath.row)
}