swift 4.2 官方文档学习笔记(十一)- Initialization + Deinitialization

Sellen Wei
2 min readDec 24, 2018

--

这张来讲一下initialization,initialization在super class中的声明有一些讲究,先来说说简单的几个:

  1. 关于designated initializer和 convenience initializer

designated initializer在一个class里可能有很多,但是designated 只能调用super的init,而不能调用class 里面其他的designated init,如果要同级别的调用,需要加上关键词convenience

2. Two-Phase Initialization:(a. property先有个初始值,b. 然后在初始的时候再customize)

In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.

详细解释2段式init:

第一阶段:

a. call .init()

b. alloc memory (只是分配,还没有初始化)

c. 所在类 stored property 内存初始化

d.父类stored property 内存初始化(层层往上,直到尽头)

e.完成

第二阶段:

a. 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 (自顶向下designated initializer开始修改customize值)

b. Finally, any convenience initializers in the chain have the option to customize the instance and to work with self.(convenience initializers 可以改写值,并且调用self)

3. 安全检查

Safety check 1

Designated initializer:all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.(property要在init之前完成初始化)

Safety check 2

Designated initializer:A designated initializer must delegate up to a superclass initializer before assigning a value to an inherited property.(否则property将被父类override,意思就是说在super.init()之前assign的值会被override,所以这个先后顺序要注意)

Safety check 3

convenience initializer:must delegate to another initializer before assigning a value to any property (including properties defined by the same class) 意思就是说assign property值要放在self.designedInitializer之后,否则也有被override的风险

Safety check 4

构造器在第一阶段构造完成之前,不能调用任何instance method,不能读取任何instance property 的值,不能引用 self 作为一个值。

  • convenience initializer:不可以被子类调用,但是可以被子类继承

Initializer Inheritance and Overriding

Unlike subclasses in Objective-C, Swift subclasses do not inherit their superclass initializers by default.

Automatic Initializer Inheritance

As mentioned above, subclasses do not inherit their superclass initializers by default. However, superclass initializers are automatically inherited if certain conditions are met.(满足以下条件,则自动继承)

Rule 1

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

subclass没有 实现任何designated initializers,则自动继承所有super class的designated initializers(如果没有继承任何initializers,则继承所有初始化器,包括designed和convenience)

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 initializers.

如果subclass继承或改写了所有superclass的designated initializers, 那么它自动继承所有superclass convenience initializers

These rules apply even if your subclass adds further convenience initializers.(增加或不增加convenience initializers不影响以上两个原则)

Designated and Convenience Initializers in Action

来看看两种initializer和继承initializer是如何实现的

Failable Initializers

使用init?在条件不满足时返回nil self

Failable Initializers for Enumerations

Propagation of Initialization Failure

Overriding a Failable Initializer

You can override a failable initializer with a nonfailable initializer but not the other way around.

Required Initializers

Write the required modifier before the definition of a class initializer to indicate that every subclass of the class must implement that initializer

在类的初始化器前添加 required 修饰符来表明所有该类的子类都必须实现该初始化器。

当子类重写父类的必要初始化器时,必须在子类的初始化器前同样添加 required 修饰符以确保当其它类继承该子类时,该初始化器同为必要初始化器。在重写父类的必要初始化器时,不需要添加 override 修饰符。

You do not have to provide an explicit implementation of a required initializer if you can satisfy the requirement with an inherited initializer.(required initializer也可以直接继承,只要满足继承法则,在这种情况下不是必须要实现该required初始化器)

Setting a Default Property Value with a Closure or Function通过闭包和函数来设置属性的默认值

如果你使用了闭包来初始化属性,请记住闭包执行的时候,实例的其他部分还没有被初始化。这就意味着你不能在闭包里读取任何其他的属性值,即使这些属性有默认值。你也不能使用隐式 self 属性,或者调用实例的方法。

学习完这一章后回答以下几个问题:

1。 convenience initializers可以在内部调用designated initializers吗?是必须调用吗?是的,详细看三个规则,便捷初始化器最终必须调用一个指定初始化器

2. 为什么要使用convenience关键词?使用了这个关键词,我能在初始化器内部做些什么?如果不加convenience是不能call同类的designed initializer的,目的就是在内部invoke class提供的的designed initializer

--

--