Подтвердить что ты не робот

Как сделать "Deep Copy" в Swift?

В Objective-C можно выполнить глубокое копирование, следуя следующему:

 Foo *foo = [[Foo alloc] init];
 Foo *foo2 = foo.copy;

Как сделать эту глубокую копию в Swift?

4b9b3361

Ответ 1

Глубокая копия

Ваш пример не является глубокой копией, как описано в StackOverflow. Для получения подлинной глубокой копии объекта часто требуется NSKeyedArchiver

Быстрое и копирование

Протокол NSCopying является Objective-C способом предоставления копий объекта, потому что все было указателем, и вам нужен способ управления генерацией копий произвольных объектов. Для произвольной копии объекта в Swift вы можете предоставить инициализатор удобства, в котором вы инициализируете MyObject другого MyObject и в init присваиваете значения от старого объекта новому объекту. Честно говоря, это в основном то, что -copy делает в Objective-C, за исключением того, что обычно нужно вызвать копию на каждом из под-объектов, так как Objective-C использует защитное копирование.

let object = MyObject()
let object2 = MyObject(object)

Почти все имеет значение pass-by-value. Почти.

Однако в Swift почти все передается по значению (, вы действительно должны нажать ссылку на вышеупомянутую ссылку), поэтому необходимо, чтобы NSCopying значительно уменьшается. Попробуйте это на игровой площадке:

var array = [Int](count: 5, repeatedValue: 0)
print(unsafeAddressOf(array), terminator: "")
let newArray = array
print(unsafeAddressOf(newArray), terminator: "")
array[3] = 3
print(array)
print(newArray)

Вы можете видеть, что назначение не является копией указателя, а фактически новым массивом. Для действительно хорошо написанного обсуждения вопросов, связанных с семантикой Swift, не относящейся к копиям по отношению к структурам и классам, я предлагаю сказочный блог Майка Эша.

Наконец, если вы хотите услышать все, что вам нужно знать от Apple, вы можете смотреть видео WWDC 2015 Value Semantics. Каждый должен смотреть это видео, он действительно очищает способ обработки памяти в Swift и как он отличается от Objective-C.

Ответ 2

Если Foo - это класс Objective-C, который реализует NSCopying, то будет работать следующее:

var foo2 = foo.copy();

-copy не определяется с помощью обозначения свойств в Foundation, поэтому вы не можете рассматривать его как свойство в Swift, хотя вы можете использовать точечную нотацию в Objective-C. Фактически, вы действительно не должны использовать точечную нотацию (даже если она является синтаксически законной), потому что -copy не является логически свойством объекта, это метод, не содержащий параметров, которые производят копию объекта.

NB это не глубокая копия, так как она не является глубокой копией в Objective-C, если только реализация не копирует все элементы экземпляра Foo.