Làm cách nào để tạo một bản sao chính xác của một mảng?
Tôi đang gặp khó khăn khi tìm thông tin về việc sao chép một mảng trong Swift.
Tôi đã thử sử dụng .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Làm cách nào để tạo một bản sao chính xác của một mảng?
Tôi đang gặp khó khăn khi tìm thông tin về việc sao chép một mảng trong Swift.
Tôi đã thử sử dụng .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Câu trả lời:
Mảng có đầy đủ ngữ nghĩa giá trị trong Swift, vì vậy không cần bất cứ thứ gì cầu kỳ.
var duplicateArray = originalArray
là tất cả những gì bạn cần.
Nếu nội dung của mảng của bạn là một kiểu tham chiếu thì có, điều này sẽ chỉ sao chép các con trỏ đến các đối tượng của bạn. Để thực hiện sao chép sâu nội dung, thay vào đó, bạn sẽ sử dụng map
và thực hiện sao chép từng phiên bản. Đối với các lớp Foundation tuân theo NSCopying
giao thức, bạn có thể sử dụng copy()
phương pháp:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Lưu ý rằng có những cạm bẫy ở đây mà ngữ nghĩa giá trị của Swift đang hoạt động để bảo vệ bạn — ví dụ: vì NSArray
đại diện cho một mảng bất biến, copy
phương thức của nó chỉ trả về một tham chiếu cho chính nó, vì vậy thử nghiệm ở trên sẽ mang lại kết quả không mong muốn.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
và tôi nhận được kết quả này: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
Có vẻ như nó đang được sao chép, bạn có biết tại sao không?
x[0] == x[1]
nhưng x[0] === y[0]
sẽ thất bại
Nate là chính xác. Nếu bạn đang làm việc với các mảng nguyên thủy, tất cả những gì bạn cần làm là gán DupateArray cho originalArray.
Để hoàn thiện, nếu bạn đang làm việc với một đối tượng NSArray, bạn sẽ làm như sau để tạo bản sao đầy đủ của một NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
Có một lựa chọn thứ ba cho câu trả lời của Nate:
let z = x.map { $0 } // different array with same objects
* ĐÃ CHỈNH SỬA * chỉnh sửa bắt đầu ở đây
Bên trên về cơ bản giống như bên dưới và thực sự sử dụng toán tử bình đẳng bên dưới sẽ hoạt động tốt hơn vì mảng sẽ không được sao chép trừ khi nó được thay đổi (đây là do thiết kế).
let z = x
Đọc thêm tại đây: https://developer.apple.com/swift/blog/?id=10
* ĐÃ CHỈNH SỬA * chỉnh sửa kết thúc tại đây
thêm hoặc bớt vào mảng này sẽ không ảnh hưởng đến mảng ban đầu. Tuy nhiên, việc thay đổi bất kỳ thuộc tính nào của đối tượng mà mảng đó nắm giữ sẽ được nhìn thấy trong mảng ban đầu. Vì các đối tượng trong mảng không phải là bản sao (giả sử mảng chứa các đối tượng chứ không phải số nguyên thủy).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, thì hãy sao chép một mảng:let z = x.map { $0.copy as! ClassX }
Đối với các đối tượng bình thường, điều có thể làm là thực hiện một giao thức hỗ trợ sao chép và làm cho lớp đối tượng thực hiện giao thức này như sau:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
Và sau đó là phần mở rộng Mảng để sao chép:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
và đó là khá nhiều, để xem mã và mẫu hãy kiểm tra ý chính này
object's
hàm init
Nếu bạn muốn sao chép các mục của một mảng của một số đối tượng lớp. Sau đó, bạn có thể làm theo mã bên dưới mà không sử dụng giao thức NSCopying nhưng bạn cần có một phương thức init sẽ nhận tất cả các tham số cần thiết cho đối tượng của bạn. Đây là mã cho một ví dụ để kiểm tra trên sân chơi.
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray