美文网首页
Swift初始化方法遇到的坑

Swift初始化方法遇到的坑

作者: LevineLi | 来源:发表于2017-06-25 20:00 被阅读47次

首先感谢这篇文章的作者:callmewhy

阶段构造

Swift 的构造过程分为两个阶段:

第一个阶段 : 每个存储型属性通过引入自己的构造器来设置初始值。
第二个阶段 : 在新实例准备使用之前进一步定制存储型属性。

安全检查

在构造的过程中, Swift 会进行四种安全检查。

安全检查一

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

比如下面这段代码就是错误的:

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
}


class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        super.init(name: name)  // ERROR!
        self.quantity = quantity
    }
}

修改后代码

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)  
        
    }
}

安全检查二

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

比如下面这段代码就是错误的:

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
}


class RecipeIngredient: Food {
    override init(name: String) {
        self.name = "WHY"   // ERROR!
        super.init(name: name)
    }
}

修改后代码

class RecipeIngredient: Food {
    override init(name: String) 
        super.init(name: name)
        self.name = "WHY" 
    }
}

安全检查三

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

比如下面这段代码就是错误的:

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
    }
    override convenience init(name: String) {
        quantity = 2    // ERROR!
        self.init(name: name, quantity: 1)
    }
}

修改后代码

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
        quantity = 2
    }
}

安全检查四

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

比如下面这段代码就是错误的:

class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        println(self.name)  // ERROR!
        super.init(name: name)
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
    }
}

修改后代码

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
        println(self.name) 
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
    }
}

相关文章

  • Swift初始化方法遇到的坑

    首先感谢这篇文章的作者:callmewhy 阶段构造 Swift 的构造过程分为两个阶段: 第一个阶段 : 每个存...

  • swift 之DESIGNATED,CONVENIENCE

    在swift中有两种初始化方法, 1.指定初始化方法 指定初始化方法其实指的就是 init 方法 2.便利初始化方...

  • Swift 的 init方法

    Swift的初始化方法是为 类、结构体、枚举使用的,它能为每个存储属性提供初始值,Swift的初始化方法和OC的初...

  • Swift 初始化方法

    初始化方法顺序 与 Objective-C 不同,Swift 的初始化方法需要保证类型的所有属性都被初始化。所以初...

  • swift 初始化方法顺序(init)

    与 Objective-C 不同,Swift 的初始化方法需要保证类型的所有属性都被初始化。所以初始化方法的调用顺...

  • Using Swift with Cocoa and Objec

    摘录 OC的初始化方法init(...)在Swift中被引为init?(...) --- 初始化可能失败init!...

  • Designated,Convenience 和 Require

    摘录至喵神的《100个swift必备Tips》 我们在深入初始化方法之前,不妨先想想Swift中的初始化想要达到一...

  • 使用CAShapeLayer做一个高性能的画板(OC版)

    Swift版原文 在touchesBegan方法中初始化一个CAShapeLayer: 初始化CAShapeLay...

  • Swift 4.0 Migration

    最近完成了Swift 4.0的迁移,记录下迁移过程中遇到的坑 Agenda Swift 4.0 简介 Swift ...

  • Swift 遇到的坑

    在swift中字典转模型,创建的model 继承自 NSObject,如果是swift 3 ,则在模型中创建属性不...

网友评论

      本文标题:Swift初始化方法遇到的坑

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