Как соответствовать NSCopying и реализовать copyWithZone в Swift 2?

Я хотел бы реализовать простой GKGameModel в Swift 2. Пример Apple выражается в Objective-C и включает это объявление метода (в соответствии с требованиями протокола NSCopying из которого наследуется GKGameModel):

- (id)copyWithZone:(NSZone *)zone {
    AAPLBoard *copy = [[[self class] allocWithZone:zone] init];
    [copy setGameModel:self];
    return copy;
}

Как это переводится в Swift 2? Является ли следующее подходящим с точки зрения эффективности и игнорирования зоны?

func copyWithZone(zone: NSZone) -> AnyObject {
    let copy = GameModel()
    // ... copy properties
    return copy
}

Ответ 1

NSZone больше не используется в Objective-C в течение длительного времени. И переданный аргумент zone игнорируется. Цитата из allocWithZone... docs:

Этот метод существует по историческим причинам; Зоны памяти больше не используются Objective-C.

Вы также можете игнорировать его.

Вот пример того, как соответствовать протоколу NSCopying.

class GameModel: NSObject, NSCopying {

  var someProperty: Int = 0

  required override init() {
    // This initializer must be required, because another
    // initializer 'init(_ model: GameModel)' is required
    // too and we would like to instantiate 'GameModel'
    // with simple 'GameModel()' as well.
  }

  required init(_ model: GameModel) {
    // This initializer must be required unless 'GameModel'
    // class is 'final'
    someProperty = model.someProperty
  }

  func copyWithZone(zone: NSZone) -> AnyObject {
    // This is the reason why 'init(_ model: GameModel)'
    // must be required, because 'GameModel' is not 'final'.
    return self.dynamicType.init(self)
  }

}

let model = GameModel()
model.someProperty = 10

let modelCopy = GameModel(model)
modelCopy.someProperty = 20

let anotherModelCopy = modelCopy.copy() as! GameModel
anotherModelCopy.someProperty = 30

print(model.someProperty)             // 10
print(modelCopy.someProperty)         // 20
print(anotherModelCopy.someProperty)  // 30

PS Этот пример предназначен для Xcode Version 7.0 beta 5 (7A176x). Особенно dynamicType.init(self).

Изменить для Swift 3

Ниже приведена реализация метода copyWithZone для Swift 3, поскольку dynamicType устарел:

func copy(with zone: NSZone? = nil) -> Any
{
    return type(of:self).init(self)
}

Ответ 2

Swift4, Helium Объект PlayItem:

// MARK:- NSCopying
convenience required init(_ with: PlayItem) {
    self.init()

    self.name  = with.name
    self.link  = with.link
    self.date  = with.date
    self.time  = with.time
    self.rank  = with.rank
    self.rect  = with.rect
    self.plays = with.plays
    self.label = with.label
    self.hover = with.hover
    self.alpha = with.alpha
    self.trans = with.trans
    self.agent = with.agent
    self.tabby = with.tabby
}

func copy(with zone: NSZone? = nil) -> Any
{
    return type(of:self).init(self)
}