Как мне сделать точную копию массива?
Мне сложно найти информацию о дублировании массива в Swift.
Я пробовал использовать .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Как мне сделать точную копию массива?
Мне сложно найти информацию о дублировании массива в Swift.
Я пробовал использовать .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Ответы:
В Swift массивы имеют полноценную семантику, так что ничего особенного не требуется.
var duplicateArray = originalArray
это все, что тебе нужно.
Если содержимое вашего массива является ссылочным типом, тогда да, это будет копировать только указатели на ваши объекты. Чтобы выполнить полное копирование содержимого, вместо этого вы должны использовать map
и выполнять копию каждого экземпляра. Для классов Foundation, которые соответствуют NSCopying
протоколу, вы можете использовать copy()
метод:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Обратите внимание, что здесь есть подводные камни, от которых семантика значений Swift работает, чтобы защитить вас - например, поскольку NSArray
представляет собой неизменяемый массив, егоcopy
метод просто возвращает ссылку на себя, поэтому приведенный выше тест даст неожиданные результаты.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
и получил такой вывод: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
не похоже, что он копируется, знаете почему?
x[0] == x[1]
но x[0] === y[0]
не удастся
Нейт прав. Если вы работаете с примитивными массивами, все, что вам нужно сделать, это назначить duplicateArray исходному массиву.
Для полноты картины, если вы работаете с объектом NSArray, вы должны сделать следующее, чтобы сделать полную копию NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
Есть третий вариант ответа Нейта:
let z = x.map { $0 } // different array with same objects
* ИЗМЕНИТЬ * редактирование начинается здесь
Выше, по сути, то же самое, что и ниже, и на самом деле использование оператора равенства ниже будет работать лучше, поскольку массив не будет скопирован, если он не будет изменен (это сделано намеренно).
let z = x
Подробнее см. Здесь: https://developer.apple.com/swift/blog/?id=10.
* ИЗМЕНИТЬ * редактирование заканчивается здесь
добавление или удаление этого массива не повлияет на исходный массив. Однако изменение любых свойств объектов, содержащихся в массиве, будет видно в исходном массиве. Поскольку объекты в массиве не являются копиями (при условии, что массив содержит объекты, а не примитивные числа).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, то продублируйте массив:let z = x.map { $0.copy as! ClassX }
Для обычных объектов можно реализовать протокол, поддерживающий копирование, и сделать так, чтобы класс объекта реализовал этот протокол следующим образом:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
А затем расширение Array для клонирования:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
и это почти все, чтобы просмотреть код и образец, проверьте эту суть
object's
функцию init
Если вы хотите скопировать элементы массива некоторого объекта класса. Затем вы можете следовать приведенному ниже коду без использования протокола NSCopying, но вам нужен метод инициализации, который должен принимать все параметры, необходимые для вашего объекта. Вот код примера для тестирования на детской площадке.
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