swift - 为什么需要在 Swift 中为 UIViewController 子类添加空构造函数

标签 swift uiviewcontroller

即使我不会将一些自定义初始化内容添加到 UIViewController 子类中,为什么我需要添加这些构造函数(空)?

    override init() {
        super.init()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

最佳答案

在 Swift 中,与某些语言不同,子类通常不会继承其父类(super class)的初始值设定项。自动初始化器继承只能在某些条件下发生。给定一个类A:

class A {
    var a: Int
    var r: Int

    init(a: Int) {
        self.r = 0
        self.a = a
    }
}

仅当满足以下两个条件时,A 类 B 才会自动继承初始值设定项:

a.子类所有新引入的属性都已分配默认值。

b.子类中没有引入新的指定初始化器,或者任何新引入的初始化器都提供了自己的父类(super class)初始化器实现:

//All values assigned, no additional initializers
class C: A {
    var c: Int = 9
}

//Provides an implementation of class A's initializer
class B: A {
    init() {
        super(a: 0)
    }
}

现在,如果我们在类中引入必需的初始化程序,事情就会变得很棘手。

class AWithRequired {
    var a: Int
    var r: Int

    init(a: Int) {
        self.r = 0
        self.a = a
    }

    required init(a: Int, r: Int) {
        self.r = r
        self.a = a
    }

}

在这种情况下,我们不能引入任何非指定的初始值设定项而不覆盖所需的初始值设定项:

//Still OK--no new initializers introduced
class BWithRequired: AWithRequired {
    var b: Int = 9
}

//Doesn't ovverride required initializer, throws an error
class CWithRequired: AWithRequired {
    init() {
        super.init(a: 0, r: 0)
    }
}   //ERROR: Required Initializer must be supplied by subclass of 'AWithRequired'

//OK, overrides required initializer
class DWithRequired: AWithRequired {
    required init(a: Int, r: Int) {
        super.init(a: 0, r: 0)
    }
}

//OK, provides non-designated initializer
class EWithRequired: AWithRequired {
    convenience init() {
        self.init(a: 0, r: 0)
    }
}

正如您从示例中看到的,绕过限制并仍然实现自定义初始值设定项的唯一方法是引入一个非指定的,例如方便初始化器。

关于swift - 为什么需要在 Swift 中为 UIViewController 子类添加空构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28834949/

相关文章:

swift - 在苹果 Swift 中使用巨大的数字

ios - 检测 map 圆覆盖中的点击总是返回 false

ios - 如何在 Swift 中正确执行此 UICollectionView.deleteItemsAtIndexPaths 操作?

ios - 使用 Swift 的 AWS DynamoDB 查询

ios - 以编程方式将数据从一个 View Controller 传递到现有 View Controller

ios - 将 View Controller 的 View 作为 subview 添加到另一个 View Controller 的 View 后出现 EXC_BAD_ACCESS 错误?

iphone - 是否有一种声明性方法可以在 IOS 中的方向更改时将背景图像从纵向版本更改为横向版本?

IOS 11 - 当另一个 pin 落后时,MKMapView pin 对话框不可点击

swift - 如何检查 UIViewController 是否已经显示?

objective-c - 在子 Controller 中查看 Controller 帧大小