gpt4 book ai didi

swift - 使用子类在 Swift 中实现 NSCopying

转载 作者:IT王子 更新时间:2023-10-29 05:27:06 26 4
gpt4 key购买 nike

考虑两个类。第一个是 Vehicle,一个符合 NSCopyingNSObject 子类:

class Vehicle : NSObject, NSCopying {

var wheels = 4

func copyWithZone(zone: NSZone) -> AnyObject {
let vehicle = self.dynamicType()
vehicle.wheels = self.wheels
return vehicle
}
}

第二个类,Starship,继承自Vehicle:

class Starship : Vehicle {

var photonTorpedos = 6
var antiGravity = true

override func copyWithZone(zone: NSZone) -> AnyObject {
let starship = super.copyWithZone(zone) as Starship

starship.photonTorpedos = self.photonTorpedos
starship.antiGravity = self.antiGravity
return starship
}
}

此代码无法编译,因为:

Constructing an object of class type 'Vehicle' with a metatype value must use a 'required' initializer.

所以我继续添加一个必需的初始化程序:

required override init () {
super.init()
}

现在应用程序编译,Starship 对象正确响应 copy()

两个问题:

  1. 为什么构造具有元类型的对象需要一个required 初始化器? (看起来我写的初始化程序什么也没做。)
  2. 有没有什么是我写错了,或者应该添加到初始值设定项中的?有没有我没有考虑的案例?

最佳答案

简短回答

如果不将 init() 标记为 required,则不能使用 self.dynamicType(),因为不能保证 Vehicle< 的子类 还将实现 init()

探索问题

看看 The Swift Programming Language: Initialization ,它提到了如何

subclasses do not inherit their superclass initializers by default

子类继承其父类(super class)的初始化器的情况是:

Assuming that you provide default values for any new properties you introduce in a subclass, the following two rules apply:

Rule 1

If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initialisers.

看例子:

class MySuperclass {
let num = 0

// MySuperclass is given `init()` as its default initialiser
// because I gave `num` a default value.
}

class MySubclass : MySuperclass {
let otherNum: Int

init(otherNum: Int) {
self.otherNum = otherNum
}
}

根据上面的信息,由于MySubclass定义的属性otherNum没有初始值,它不会自动继承init()来自 MySuperclass

现在假设我想将以下方法添加到 MySuperclass:

func myMethod() {
println(self.dynamicType().num)
}

你会得到你所描述的错误,因为不能保证 MySuperclass 的子类会实现 init()(在这个例子中他们不会)。

要解决此问题,您需要将 init() 标记为 required,以确保 MySuperclass 的所有子类都实现 init (),因此调用 self.dynamicType() 是一件有效的事情。这与您的问题中的问题相同:Swift 知道 Vehicle 实现 init(),但是它不知道任何子类将实现 init() 所以你需要让它成为必需的

另一个不适合您的示例的解决方案是将 Vehicle 标记为 final,这意味着 Vehicle 不能子类化。然后你就可以使用 self.dynamicType();但在这种情况下,您也可以只使用 Vehicle()

关于swift - 使用子类在 Swift 中实现 NSCopying,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28144475/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com