如何在Swift2中遵循NSCopying和实现copyWithZone?
How to conform to NSCopying and implement copyWithZone in Swift 2?
我想在Swift中实现一个简单的GKGameModel
2. Apple的示例在Objective-C中表示并包含此方法声明(根据协议NSCopying
的要求GKGameModel
从中继承):
- (id)copyWithZone:(NSZone *)zone {
AAPLBoard *copy = [[[self class] allocWithZone:zone] init];
[copy setGameModel:self];
return copy;
}
这如何转化为 Swift2?就效率和忽略区域而言,以下是否合适?
func copyWithZone(zone: NSZone) -> AnyObject {
let copy = GameModel()
// ... copy properties
return copy
}
NSZone
已经很久没有在Objective-C 中使用了。并忽略传递的 zone
参数。引自 allocWithZone...
文档:
This method exists for historical reasons; memory zones are no longer
used by 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
P.S。此示例适用于 Xcode 版本 7.0 beta 5 (7A176x)。特别是 dynamicType.init(self)
.
编辑 Swift 3
下面是 Swift 3 的 copyWithZone 方法实现,因为 dynamicType
已被弃用:
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)
}
A COPY OF ALREADY PRESENT 数组的最后一个元素被复制并使用值创建。
工作于 Xcode 12.1 swift 5
// Model class 这里的model定义为class
import Foundation
class SampleClass: NSObject, NSCopying, Codable {
var variable1: String?
var variable2: String?
var variable3: String?
required override init() {
}
required init(_ model: SampleClass) {
self.variable1 = model.variable1
self.variable2 = model.variable2
self.variable3 = model.variable3
}
func copy(with zone: NSZone? = nil) -> Any
{
return type(of:self).init(self)
}
init(_ dictionary: [String: Any]) {
self.variable1 = dictionary["variable1"] as? String
self.variable2 = dictionary["variable2"] as? String
self.variable3 = dictionary["variable3"] as? String
}
}
// How to use it in ViewController in a button where data from the model is already in a array of dictionary
@IBAction func duplicate(_ sender: Any) {
if self.currentArray > 0 {
if let content = self.self.currentArray.last {
let anotherCopy = content.copy() as! SampleClass
self.self.currentArray.append(anotherCopy)
}
}
}
我想在Swift中实现一个简单的GKGameModel
2. Apple的示例在Objective-C中表示并包含此方法声明(根据协议NSCopying
的要求GKGameModel
从中继承):
- (id)copyWithZone:(NSZone *)zone {
AAPLBoard *copy = [[[self class] allocWithZone:zone] init];
[copy setGameModel:self];
return copy;
}
这如何转化为 Swift2?就效率和忽略区域而言,以下是否合适?
func copyWithZone(zone: NSZone) -> AnyObject {
let copy = GameModel()
// ... copy properties
return copy
}
NSZone
已经很久没有在Objective-C 中使用了。并忽略传递的 zone
参数。引自 allocWithZone...
文档:
This method exists for historical reasons; memory zones are no longer used by 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
P.S。此示例适用于 Xcode 版本 7.0 beta 5 (7A176x)。特别是 dynamicType.init(self)
.
编辑 Swift 3
下面是 Swift 3 的 copyWithZone 方法实现,因为 dynamicType
已被弃用:
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)
}
A COPY OF ALREADY PRESENT 数组的最后一个元素被复制并使用值创建。
工作于 Xcode 12.1 swift 5
// Model class 这里的model定义为class
import Foundation
class SampleClass: NSObject, NSCopying, Codable {
var variable1: String?
var variable2: String?
var variable3: String?
required override init() {
}
required init(_ model: SampleClass) {
self.variable1 = model.variable1
self.variable2 = model.variable2
self.variable3 = model.variable3
}
func copy(with zone: NSZone? = nil) -> Any
{
return type(of:self).init(self)
}
init(_ dictionary: [String: Any]) {
self.variable1 = dictionary["variable1"] as? String
self.variable2 = dictionary["variable2"] as? String
self.variable3 = dictionary["variable3"] as? String
}
}
// How to use it in ViewController in a button where data from the model is already in a array of dictionary
@IBAction func duplicate(_ sender: Any) {
if self.currentArray > 0 {
if let content = self.self.currentArray.last {
let anotherCopy = content.copy() as! SampleClass
self.self.currentArray.append(anotherCopy)
}
}
}