你真的弄懂了Swift初始化吗?

作者: Hollylord | 来源:发表于2016-01-08 16:37 被阅读4147次

什么是初始化

初始化就是:给存储属性赋值。像下面这样

struct Fahrenheit {    
  var temperature: Double    
  init() {        
    temperature = 32.0    
  }
}

注意:当你对给一个属性分配一个默认值的时候,它会调用它相对应的初始化方法,这个值是对属性直接设置的,不会通知它对应的观察者。

下面有2种初始化方法:

  • 默认初始化方法
    Swift为每一个结构或者基类提供了默认的构造器,来初始化它们所包含的所有属性。默认构造器将会创建一个新的实例然后将它们的属性设置为默认值
class ShoppingListItem {    
  var name: String?    
  var quantity = 1    
  var purchased = false
}
var item = ShoppingListItem()
  • 自定义初始化
    你可以根据输入的参数来自定义初始化过程和可选的属性类型,或者在初始化的时候修改静态属性。
    带参数的初始化方法叫自定义初始化。
struct Celsius {    
  var temperatureInCelsius: Double = 0.0    

  init(fromFahrenheit fahrenheit: Double) {        
    temperatureInCelsius = (fahrenheit - 32.0) / 1.8    
  }    

  init(fromKelvin kelvin: Double) {        
      temperatureInCelsius = kelvin - 273.15    
  }
}

当然上面只是基础知识几个概念,下面才是重点。

类的继承及其初始化

  1. 类的初始化过程

两段式构造过程

Swift 中类的构造过程包含两个阶段。第一个阶段,每个存储型属性通过引入它们的类的构造器来设置初始值。当每一个存储型属性值被确定后,第二阶段开始,它给每个类一次机会在新实例准备使用之前进一步定制它们的存储型属性。

阶段 1
某个指定构造器或便利构造器被调用;
完成新实例内存的分配,但此时内存还没有被初始化;
指定构造器确保其所在类引入的所有存储型属性都已赋初值。存储型属性所属的内存完成初始化;
指定构造器将调用父类的构造器,完成父类属性的初始化;
这个调用父类构造器的过程沿着构造器链一直往上执行,直到到达构造器链的最顶部;
当到达了构造器链最顶部,且已确保所有实例包含的存储型属性都已经赋值,这个实例的内存被认为已经完全初始化。此时阶段1完成。

Paste_Image.png

阶段 2
从顶部构造器链一直往下,每个构造器链中类的指定构造器都有机会进一步定制实例。构造器此时可以访问self、修改它的属性并调用实例方法等等
最终,任意构造器链中的便利构造器可以有机会定制实例和使用self。

Paste_Image.png
  1. 如何初始化

1、自定义初始化方法要先调用自己类默认初始化方法,自己重写默认初始化方法要先调用父类默认初始化方法
2、应该要先调用父类的构造器或者自身的默认构造器,以防止先给属性赋值了然后才调用父类或者自身的默认构造器把以前的赋值覆盖了

Paste_Image.png
  1. 关于初始化的继承
    规则 1
    如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器。

规则 2
如果子类提供了所有父类指定构造器的实现--不管是通过规则1继承过来的,还是通过自定义实现的--它将自动继承所有父类的便利构造器。

  1. Swift的4种安全检查
    安全检查 1
    指定构造器必须保证它所在类引入的所有属性都必须先初始化完成,之后才能将其它构造任务向上代理给父类中的构造器。

安全检查 2
指定构造器必须先向上代理调用父类构造器,然后再为继承的属性设置新值。如果没这么做,指定构造器赋予的新值将被父类中的构造器所覆盖。

安全检查 3
便利构造器必须先代理调用同一类中的其它构造器,然后再为任意属性赋新值。如果没这么做,便利构造器赋予的新值将被同一类中其它指定构造器所覆盖。

安全检查 4
构造器在第一阶段构造完成之前,不能调用任何实例方法、不能读取任何实例属性的值,也不能引用self的值。

代码实例

class Food { 
    var name: String 
    //指定的初始化器
    init(name: String) { 
        self.name = name 
    } 
    //便携初始化器
    convenience init() { 
        self.init(name: "[Unnamed]") 
    } 
} 
Paste_Image.png
class RecipeIngredient: Food { 
    var quantity: Int 
    //重载指定初始化器
    init(name: String, quantity: Int) { 
    //首先初始化自己本类的存储属性
        self.quantity = quantity 
    //然后调用初始化父类的存储属性
        super.init(name: name) 
    } 
    convenience init(name: String) { 
        self.init(name: name, quantity: 1) 
    } 
} 
Paste_Image.png
class ShoppingListItem: RecipeIngredient { 
    var purchased = false 
    var description: String { 
    var output = "\(quantity) x \(name.lowercaseString)" 
        output += purchased ? " ?" : " ?" 
        return output 
    } 
} 

由于它为自己引入的所有属性都提供了默认值,并且自己没有定义任何构造器,ShoppingListItem将自动继承所有父类中的指定构造器和便利构造器。

相关文章

  • 你真的弄懂了Swift初始化吗?

    什么是初始化 初始化就是:给存储属性赋值。像下面这样 注意:当你对给一个属性分配一个默认值的时候,它会调用它相对应...

  • Swift 5.1 (14) - 初始化和反初始化

    Swift 5.1 (14) - 初始化和反初始化Swift 5.1 (14) - 初始化和反初始化

  • 知识点不会融合怎么办?

    说到知识点,人人都会说:我学了呀,会了呀,一问到:懂了吗?懂了。真的懂了吗?真的懂了呀。确定吗?确定啊。那你把这个...

  • 如何阅读?20170213

    你真的会阅读吗?你读过的书真的读懂了吗?你理解了作者想要表达的概念、故事、逻辑了?你真的会选书吗?什么样的书才适合...

  • 编程挑战:你是Swift忍者吗?

    编程挑战:你是Swift忍者吗? 编程挑战:你是Swift忍者吗?

  • 如何让更多的人升级自己的操作系统,实现财富自由

    很多人都在说,我懂了那么多道理,为什么依然过不好这一生?其实你是真的懂了那些道理吗?即便是懂了那些道理,你有运用这...

  • swift初始化常见错误

    importUIKit 前言:swift的初始化过程真的比oc的初始化难啊难,需要反反复复看。为了更好地理解、快速...

  • 赖佩霞 | 我是个什么样的观众?

    听别人说话,你真的听懂了他的意思吗? 说话时,你又真的了解自己正在做什么吗? 甲:他真的很讨人厌,每次都那样,他就...

  • 你真的读懂了论语吗?

    -序- 儒学虽然历经许多波折,但是依然穿过了两千年的历史迷雾,流传到了今天。 《论语》作为儒家经典,我们从小就耳濡...

  • 你真的读懂了空虚吗

    懒惰 人总是会把一些困难的(非必需的)事情一拖再拖,最后真的就没必要(不可能)完成,这种懒惰的性情会像个毒品毒害我...

网友评论

  • LoveY34:class RecipeIngredient: Food {
    var quantity: Int
    //重载指定初始化器
    init(name: String, quantity: Int) {
    //首先初始化自己本类的存储属性
    self.quantity = quantity
    //然后调用初始化父类的存储属性
    super.init(name: name)
    }
    convenience init(name: String) {
    self.init(name: name, quantity: 1)
    }
    }

    不是说在初始化第一阶段完成前是不能引用self嘛?为什么这里在调用super.init(name: name) 之前使用self?
  • omni_Hsin:翻译的官方文档。。。。。

本文标题:你真的弄懂了Swift初始化吗?

本文链接:https://www.haomeiwen.com/subject/tinfkttx.html