Объекты массива Swift swap
Я не могу поменять массив строк на ячейку reorder
var scatola : [String] = []
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
swap(&scatola[fromIndexPath.row], &scatola[toIndexPath.row])
}
этот код бросает: обратная запись inout в вычисляемое свойство "scatola" происходит в нескольких аргументах для вызова, вводя недопустимое сглаживание
Как правильно это сделать?
3 ответов
обновление: по состоянию на Swift 3.2 / 4 (Xcode 9) вы должны использовать swapAt()
метод
коллекция
scatola.swapAt(fromIndexPath.row, toIndexPath.row)
потому что передача массива как два разных
inout
аргументы той же функции больше не являются законными,
сравнить SE-0173 добавить 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 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
кроме того,
let f = fromIndexPath.row, t = toIndexPath.row
(scatola[f], scatola[t]) = (scatola[t], scatola[f])
запуск Xcode 9, вы можете написать:
@objc override func tableView(_ tableView: UITableView,
moveRowAt sourceIndexPath: IndexPath,
to destinationIndexPath: IndexPath) {
scatola.swapAt(sourceIndexPath.row, destinationIndexPath.row)
}