2014-10-10 3 views
10

Я не могу поменять массив строк на ячейку перезаказаSwift массив своп объекты

var scatola : [String] = [] 

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

этот код бросает: INOUT обратной записи в вычисленную собственность «Scatola» происходит в нескольких аргументов называют, вводя недопустимый ступенчатость

Каков правильный способ сделать это?

+2

Покажите нам декларацию 'scatola'. –

+0

var scatola: [String] = [] – Enlil

ответ

16

Update: По Swift 3,2/4 (Xcode 9) вы должны использовать метод swapAt() на В коллекции

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

, потому что передача массива в виде двух различных inout аргументов в такая же функция больше не является законной, сравнить SE-0173 Add MutableCollection.swapAt(_:_:)).


Update: Я тестировал код снова 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 
+1

в Swift 3.2 и выше, вам нужно написать 'swapAt (0, 1)'. –

15

В качестве альтернативы,

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

Отличное решение!+1 – ZYiOS

+0

Отличное и лаконичное решение, +1 –

+1

И это более безопасно, затем swap, потому что swap падает, если индексы одинаковы. Не может произойти в этом примере, но, как правило, индексы должны быть проверены перед использованием swap. +1 – Darko

0

Начиная Xcode 9, вы можете написать:

@objc override func tableView(_ tableView: UITableView, 
       moveRowAt sourceIndexPath: IndexPath, 
        to destinationIndexPath: IndexPath) { 
    scatola.swapAt(sourceIndexPath.row, destinationIndexPath.row) 
} 
Смежные вопросы