0. 没有一个 initializer 时,Class 和 Struct 有 default initializer
Swift provides a default initializer for any structure or class that provides default values for all of its properties and does not provide at least one initializer itself.
1. Struct 没有 custom initializers 时,它还有 memberwise initializer
Structure types automatically receive a memberwise initializer if they do not define any of their own custom initializers.
2. Struct 想有 custom initializers,又想保留它的 default initializer 和 memberwise initializer,该怎么办?答案是在它的 extension
中定义 custom initializers
struct Size { var width = 0.0, height = 0.0 } extension Size { init(square: Double) { self.init(width: square, height: square) // Value 类型的 Initializer Delegation 很简单,就调 self.init } } let size1 = Size() let size2 = Size(width: 3, height: 2) let size3 = Size(square: 2)
3. Value 类型的 Initializer Delegation 很简单,就调 self.init
4. Class 类型的 Initializer Delegation 简单记法
- Designated initializers must always delegate up.
- Convenience initializers must always delegate across.
5. Class 的初始化是分两阶段进行的(Two-Phase Initialization)
第一阶段是分配内存和为每一个 stored 属性初始化,第一阶段完成后第二阶段才可以访问 self、修改属性、调用实例方法等。
记住两点:
Phase 1
- A designated or convenience initializer is called on a class.
- Memory for a new instance of that class is allocated. The memory is not yet initialized.
- A designated initializer for that class confirms that all stored properties introduced by that class have a value. The memory for these stored properties is now initialized.
- The designated initializer hands off to a superclass initializer to perform the same task for its own stored properties.
- This continues up the class inheritance chain until the top of the chain is reached.
- Once the top of the chain is reached, and the final class in the chain has ensured that all of its stored properties have a value, the instance’s memory is considered to be fully initialized, and phase 1 is complete.
Phase 2
- Working back down from the top of the chain, each designated initializer in the chain has the option to customize the instance further. Initializers are now able to access self and can modify its properties, call its instance methods, and so on.
- Finally, any convenience initializers in the chain have the option to customize the instance and to work with self.
6. Swift 中的子类 默认 是不继承父类的初始化方法的,但可以重载父类的 designated initializer, default initializer,方法前加 override 修饰词
7. 正因为子类不继承父类的初始化方法,会出现下面两种情况时:
- 子类的 Convenience initializer 跟父类的 Designated initializer 相同时,被认为是重载,即使是 Convenience initializer 要加 override 修饰词。
- 子类的 Designated initializer 或 Convenience initializer 跟父类的 Convenience initializer 相同时,不被认为是重载,不用加 override 修饰词。
8. 子类默认不继承父类的初始化方法,但出现下面规则时 自动继承 父类的初始化方法
- 规则 1: 子类没有定义任何的 Designated initializer,它会自动继承父类所有的 Designated initializer。
- 规则 2: 子类定义了父类所有的 Designated initializer 或通过规则 1 继承,它会自动继承父类所有的 Convenience initializer。
9. 可失败的(Failable Initializer)初始化方法 init?(),在其中用 return nil 表示初始化失败,在实例化时是一个 optional 值。
class Product { let name: String init?(name: String) { if name.isEmpty { return nil } self.name = name } }
10. Failable Initializer 的 Initializer Delegation 跟其他初始化方法的 Initializer Delegation 规则一样
A failable initializer of a class, structure, or enumeration can delegate across to another failable initializer from the same class, structure, or enumeration. Similarly, a subclass failable initializer can delegate up to a superclass failable initializer.
11. Failable Initializer 的重载跟其他初始化方法的重载规则也一样,而且子类可重载父类的 Failable Initializer 成为 nonfailable Initializer,此时子类要在其中 force-unwrap 父类的 Failable Initializer 结果
12. 初始化方法用 required 修饰时,表示继承链上的所有子类必须实现这个方法
13. 抛出错误类型的初始化方法,它不但可以 Failable,而且可以知道初始化失败的错误类型
enum ProductError: ErrorType { case EmptyName case InvalidName } class Product { let name: String init(name: String) throws { if name.isEmpty { throw ProductError.EmptyName } else if name.characters.count > 1024 { throw ProductError.InvalidName } self.name = name } } do { let product = try Product(name: "") } catch ProductError.EmptyName { print("EmptyName") // "EmptyName/n" } catch ProductError.InvalidName { print("InvalidName") } let product = try? Product(name: "") // nil
原文 http://c0ming.me/swift-note-initialization/