【问题标题】:Swift swap array objectsSwift 交换数组对象
【发布时间】:2014-12-06 02:16:39
【问题描述】:

我无法在单元格重新排序时交换字符串数组:

var scatola : [String] = []

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

这段代码抛出:

inout 写回计算属性 'scatola' 出现在要调用的多个参数中,引入了无效的别名

正确的做法是什么?

【问题讨论】:

  • 向我们展示scatola的声明。
  • var scatola : [字符串] = []

标签: arrays uitableview swift


【解决方案1】:

更新: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])
    }
}

编译器输出:

错误:inout writeback to computed property 'array' 发生在多个要调用的参数中,引入了无效的别名 交换(&数组[0],&数组[1]) ^~~~~~~~ 注意:这里发生并发写回 交换(&数组[0],&数组[1]) ^~~~~~~~

我还没有掌握 讨论的内容完全(这里为时已晚:),但有一个提议 “解决方法”,即将属性标记为最终的(这样你就不能覆盖它 在子类中):

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

【讨论】:

  • 在 Swift 3.2 及更高版本中,您需要编写 swapAt(0, 1)
【解决方案2】:

启动 Xcode 9,你可以这样写:

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

【讨论】:

    【解决方案3】:

    或者,

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

    【讨论】:

    • 伟大而简洁的解决方案,+1
    • 而且它比交换更安全,因为如果索引相同,交换会崩溃。在此示例中不会发生,但通常必须在使用交换之前检查索引。 +1
    • 这也适用于对象数组。交换不适用于对象数组,它最终会用同一个对象替换两个索引
    猜你喜欢
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多