web-dev-qa-db-fra.com

Comment se conformer à NSCopying et implémenter copyWithZone dans Swift 2?

Je voudrais implémenter un simple GKGameModel dans Swift 2. L'exemple d'Apple est exprimé en Objective-C et inclut cette déclaration de méthode (comme requis par le protocole NSCopyingfrom dont GKGameModel hérite):

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

Comment cela se traduit-il en Swift 2? Les éléments suivants sont-ils appropriés en termes d'efficacité et de zone d'ignorance?

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

NSZone n'est plus utilisé dans Objective-C depuis longtemps. Et l'argument zone passé est ignoré. Citation des documents allocWithZone...:

Cette méthode existe pour des raisons historiques; les zones de mémoire ne sont plus utilisées par Objective-C.

Vous pouvez également l'ignorer.

Voici un exemple de conformité au protocole 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

P.S. Cet exemple est pour Xcode Version 7.0 beta 5 (7A176x). Surtout la dynamicType.init(self).

Modifier pour Swift

Ci-dessous, l'implémentation de la méthode copyWithZone pour Swift 3 as dynamicType a été déconseillé:

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

Objet PlayItem de Swift4, Helium :

// 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)
}
1
slashlos