当前位置: 首页 > 面试题库 >

在Swift中使用子类实现NSCopying

方楷
2023-03-14
问题内容

考虑两个类。第一个是Vehicle,其NSObject子类符合NSCopying

class Vehicle : NSObject, NSCopying {

    var wheels = 4

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

第二类Starshiphtml" target="_blank">继承自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
    }
}

该代码无法编译,因为:

使用元类型值构造“ Vehicle”类类型的对象必须使用“ required”初始化程序。

因此,我继续添加所需的初始化程序:

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

现在,应用程序可以编译,并且Starship对象可以copy()正确响应。

两个问题:

  1. 为什么构造具有元类型的对象需要required初始化程序?(看来我编写的初始化程序没有任何作用。)
  2. 我写错了什么,还是 应该 添加到初始化程序?我有没有考虑的情况?

问题答案:

简短答案

您不能在self.dynamicType()没有标记的情况下使用init()required因为不会保证Vehiclewill的子类也将实现init()

探索问题

看一下《 The Swift Programming
Language:Initialization》

,其中提到了

子类默认情况下不继承其超类初始化程序

子类 继承其超类的初始化程序的情况是:

假设为子类中引入的任何新属性提供默认值,则适用以下两个规则:

规则1

如果您的子类没有定义任何指定的初始化器,它将自动继承其所有超类的指定初始化器。

规则二

如果您的子类提供了其所有超类指定的初始化程序的实现(通过按照规则1继承它们,或通过提供自定义实现作为其定义的一部分),那么它将自动继承所有超类便利性初始化程序。

看一下示例:

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,以确保MySuperclassImplement的所有子类init(),因此调用self.dynamicType()是正确的做法。问题与您的问题相同:Swift知道Vehicle实现init(),但是它不知道任何子类将实现init(),因此您需要使其实现required

在您的示例中不适合的另一种解决方案是将标记Vehiclefinal,表示Vehicle不能被子类化。这样就可以使用self.dynamicType();
但您最好还是Vehicle()在这种情况下使用。



 类似资料:
  • 问题内容: 我在Swift操场上有以下示例,试图在Swift中实现一个副本构造函数: 问题在于这实际上并不能以当前形式进行编译。在子类中的 方法上,报告此错误: 如果它不是 构造函数 ,就好比是常规的,那么这个问题 就很有意义 了,您可以传递超类中期望的类型,但在子类中已重写该类型以限制更多: __ 但是事实是它是 构造函数 ,这使我相信我应该能够重写它并提供不同的方法签名,因为在编译时绝对知道对

  • 问题内容: 在Objective C中很简单:只需更新main.m文件并更改UIApplicationMain()参数即可 但是由于该指南指出,因此没有main.m文件 “在全局范围内编写的代码被用作程序的入口点,因此您不需要主要功能。” 那么,如何快速将UIApplication子类化?有什么建议吗? 问题答案: 注意: 如果您正在寻找以前的语法,请在2019年6月对XCode 10.1和Swi

  • 我是斯威夫特编程新手,请告诉我如何用代码在斯威夫特实现单例类。 在obj-c中我知道 斯威夫特怎么样

  • 问题内容: 我已经在Swift中实现了一个使用字典键的Set。我想实现一个addAll(sequence)方法,该方法在Set中的Elements上采用任何序列类型,但是出现一个没有意义的错误。这是我的代码 我在XCode 6.1和6.0.1中遇到此错误。 我想遵循Array的extend方法的语义,但是该类型签名甚至不为我编译。 我做错了什么,还是应该提交雷达? 编辑 :刚刚找到https://

  • 问题内容: 我想使用Accelerate框架扩展[Float]和[Double],但每个框架都需要不同的实现。 我尝试了明显的方法: 并得到这个错误: “必须在具有’where’子句指定约束的非专用泛型’Array’上声明受约束的扩展” 以这种方式在Swift 2中扩展泛型类型是否可行? 我的代码现在可以按预期工作了。这是显示使用Accelerate框架求和的示例。 问题答案: 如果只想扩展特定类

  • 问题内容: 我遇到了以下代码(Swift 3.1)中解释的问题: 因此,我希望在调用后应打印 _“ SubClassmethodA”_文本。但是由于某种原因,调用了from协议扩展的默认实现。但是,呼叫按预期方式工作。 是协议方法调度中的另一个Swift错误,还是我丢失了一些东西并且代码正常工作? 问题答案: 这就是协议当前调度方法的方式。 协议见证表(有关更多信息,请参见WWDC谈话)用于在协议