2014-10-10 21 views
10

Tôi không thể trao đổi một mảng các chuỗi trên di động sắp xếp lạimảng swap Swift đối tượng

var scatola : [String] = [] 

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

mã này ném: writeback inout để sở hữu 'scatola' tính xảy ra ở nhiều đối số để gọi, giới thiệu hợp lệ răng cưa

cách phù hợp để làm điều đó là gì?

+2

Cho chúng tôi thấy tuyên bố của 'scatola'. –

+0

var scatola: [String] = [] – Enlil

Trả lời

16

Cập nhật: Tính đến Swift 3.2/4 (Xcode 9) bạn phải sử dụng phương pháp swapAt() trên bộ sưu tập

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

vì đi qua các mảng như hai khác nhau inout đối số cho các cùng một chức năng không còn hợp pháp, so sánh SE-0173 Add MutableCollection.swapAt(_:_:)).


Cập nhật: Tôi đã thử nghiệm mã một lần nữa với Xcode 6.4, và các vấn đề không xảy ra nữa. Nó biên dịch và chạy như mong đợi.


(câu trả lời Cũ :) tôi cho rằng scatola là một tài sản được lưu trữ trong bộ điều khiển xem:

var scatola : [Int] = [] 

Vấn đề của bạn dường như có liên quan đến các vấn đề được thảo luận trong https://devforums.apple.com/thread/240425. Nó đã có thể được sao chép với: sản lượng

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

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

Compiler:

 
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]) 
       ^~~~~~~~ 

tôi chưa nắm được nội dung của các cuộc thảo luận hoàn toàn (quá muộn đây :), nhưng có một đề xuất "Cách giải quyết", cụ thể là để đánh dấu tài sản là cuối cùng (vì vậy mà bạn không thể ghi đè lên nó trong một lớp con):

final var scatola : [Int] = [] 

Một cách giải quyết mà tôi tìm thấy là để có được một con trỏ trên lưu trữ mảng cơ bản:

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

Tất nhiên, giải pháp fool-proof sẽ chỉ đơn giản là

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

trong Swift 3.2 trở lên, bạn cần phải viết 'swapAt (0, 1)'. –

15

Ngoài ra,

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

Giải pháp tuyệt vời!+1 – ZYiOS

+0

Giải pháp tuyệt vời và súc tích, +1 –

+1

Và nó an toàn hơn sau đó trao đổi, vì trao đổi bị treo nếu các chỉ mục giống nhau. Không thể xảy ra trong ví dụ này nhưng nói chung các chỉ mục phải được kiểm tra trước khi sử dụng trao đổi. +1 – Darko

0

Bắt đầu từ Xcode 9, bạn có thể viết:

@objc override func tableView(_ tableView: UITableView, 
       moveRowAt sourceIndexPath: IndexPath, 
        to destinationIndexPath: IndexPath) { 
    scatola.swapAt(sourceIndexPath.row, destinationIndexPath.row) 
} 
Các vấn đề liên quan