Swift 2.で単純なGKGameModel
を実装したいと思います。Appleの例はObjective-Cで表現されており、このメソッド宣言が含まれています(プロトコルNSCopying
fromでの必要に応じて) 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
}
NSZone
は、Objective-Cでは長い間使用されていません。また、渡されたzone
引数は無視されます。 _allocWithZone...
_ドキュメントからの引用:
この方法は歴史的な理由で存在しています。メモリゾーンは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
_
追伸この例は、Xcodeバージョン7.0ベータ5(7A176x)用です。特にdynamicType.init(self)
。
Swift 3の編集
以下は、Swift 3 for dynamicType
が廃止されたためのcopyWithZoneメソッドの実装です。
_func copy(with zone: NSZone? = nil) -> Any
{
return type(of:self).init(self)
}
_
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)
}