Swift 中的初始化:init


Swift 构造器

Swift 的 构造过程和 OC 不一样,Swift 中构造方法没有返回值

Swift 中结构体和类的构造器有一些却别,结构体有默认构造器,类型没有默认构造器。

相同方法名的构造器,实参不一样则表示构造器也不一样

构造过程其实就是保证类或结构体中的存储属性完全初始化完成

实参:函数参数名

形参:函数内部使用的参数名

Swift 构造函数可以不带实参标签,用_ 来表示,和函数一致

构造器可以对常量属性进行赋值(一次)

默认构造器(有自定义构造器将无法访问)

如果结构体或类的存储属性都已经有默认初始值,且没有提供自定义的构造器,那么会有一个默认的构造器init()

结构体的逐一成员构造器(有自定义构造器将无法访问)

结构体如果有存储属性没有默认初始值,且没有提供自定义构造器,那么会自动有一个逐一成员构造器,即,每个实参就是对应一个还没有默认值的存储属性

struct Size {
var width = 0.0, height = 0.0
}

let size = Size(width: 20, height: 20)

假如,需要同时存在 默认构造器、逐一成员构造器,自定义构造器都能使用,可以将自定义构造器放到extension拓展中。

值类型构造器代理

值类型没有继承,其构造器代理也相对简单,只要在自定义构造器中引用 同类型中的其他构造器。如调用 self.init()

struct Size {
var width = 0.0 , height = 0.0
}

struct Point {
var x = 0.0 , y = 0.0
}

struct Rect {
var point = Point()
var size = Size()
init() {}
init(point:Point, size: Size) {
self.point = point
self.size = size
}
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}

将自定义构造器移到 extentsion 中

struct Size {
var width = 0.0 , height = 0.0
}

struct Point {
var x = 0.0 , y = 0.0
}

struct Rect {
var point: Point
var size: Size
}

extension Rect {
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}
let rect2 = Rect(point: Point(x: 100, y: 100), size: Size(width: 200, height: 200))
let rect3 = Rect(center: Point(x: 100, y: 0), size: Size(width: 200, height: 200))

如果是直接放到结构体主体中,Xcode 会直接报错

struct Rect {
var point: Point
var size: Size
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}

类的构造过程

类因为有继承关系,所以类的构造过程比较复杂。

类类型中有几种构造器

  • 便利构造器: convenience 修饰的构造器

  • 指定构造器 : 常规看到的构造器,不带修饰关键字的构造器

  • 必要构造器: required 修饰的构造器

必要构造器

子类必须实现的构造器,在子类实现必要构造器时,必须要在构造器前面也加 required 修饰,表明该构造器也用于继承链后面的子类,重写必要构造器时不需要 override 修饰

required init(parameters) {
statements
}

如果子类继承的构造器已经满足必要构造器的要求,则无需显示重写。如果子类没有定义任何指定构造器,则会自动继承父类所有指定构造器

便利构造器

构造器前面增加 convenience 修饰

convenience init(parameters) {
statements
}
指定构造器

指定构造器和结构体一样,普通的构造器写法

init(parameters) {
statements
}

类类型构造器的代理规则

  • 指定构造器必须调用其父类的指定构造器

  • 便利构造器必须调用该类定义的其他构造器

  • 便利构造器最后必须调用指定构造器

指定构造器必须向上代理

便利构造器必须要横向代理

这样就可以保证构造其能构完全的初始化实例

构造器的自动继承

假设已经为子类中引入的所有新属性都提供了默认值,以下 2 个规则将适用:

  • 如果子类没有定义任何指定构造器,它将自动继承父类所有的指定构造器

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

子类可以将父类的指定构造器实现为便利构造器来满足规则 2。

可失败构造器

可失败构造器是 类似可选值的写法,构造过程在特定条件下返回会 nil,子类重写可失败构造器,可以将其重写为不可失败构造器,反之不行。

    init?(parameters) {
if 条件为 true {
return nil
}
statements
}

可失败构造器的参数名和参数类型,不能与不可失败构造器相同


原文始发于微信公众号(三万之一):Swift 中的初始化:init

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/231271.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!