Swift初始化器与可选链的使用方法介绍

目录
  • 初始化器
    • required
    • 属性观察器
    • 可失败初始化器
    • 反初始化器(deinit)
  • 可选链(Optional Chaining)

初始化器

required

用required修饰指定初始化器,表明其所有子类都必须实现该初始化器(通过继承或者重写实现)

如果子类重写了required初始化器,也必须加上required,不用加上override

class Person {
    required init() {}
    init(age: Int) {}
}
class Student: Person {
    init(no: Int) {
        super.init(age: 0)
    }
    required init() {
        super.init()
    }
}

属性观察器

父类的属性在它自己的初始化器中赋值不会触发属性观察器,但在子类的初始化器中赋值会触发属性观察器

class Person {
    var age: Int {
        willSet {
            print("willSet", newValue)
        }
        didSet {
            print("didSet", oldValue, age)
        }
    }
    init() {
        self.age = 0
    }
}
class Student: Person {
    override init() {
        super.init()
        self.age = 1
    }
}

可失败初始化器

类、结构体、枚举都可以使用init?定义可失败初始化器

class Person {
    var name: String
    init?(name: String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
}

不允许同时定义参数标签、参数个数、参数类型相同的可失败初始化器和非可失败初始化器

可以用init!定义隐式解包的可失败初始化器

可失败初始化器可以调用非可失败初始化器,非可失败初始化器调用可失败初始化器需要进行解包

class Person {
    var name: String
    init?(name: String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
    convenience init() {
        self.init(name: "")!
    }
}

如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行

可以用一个非可失败初始化器重写一个可失败初始化器,但反过来是不行的。

反初始化器(deinit)

deinit叫做反初始化器,类似于C++的析构函数、OC中的dealloc方法

当类的实例对象被释放内存时,就会调用实例对象的deinit方法

class Person {
    deinit {
        print("Person对象销毁了")
    }
}

deinit不接受任何参数,不能写小括号,不能自行调用

父类的deinit能被子类继承

子类的deinit实现执行完毕后会调用父类的deinit

可选链(Optional Chaining)

class Car {
    var price = 0
}
class Dog {
    var weight = 0
}
class Person {
    var name: String = ""
    var dog: Dog = Dog()
    var car: Car? = Car()
    func age() -> Int {
        18
    }
    func eat() {
        print("Person eat")
    }
    subscript(index: Int) -> Int {
        return index
    }
}
var person: Person? = Person()
var age = person?.age()//Int? Optional(18)
var age1 = person!.age() // Int
var name = person?.name //String?
var index = person?[6] // Int?

如果可选项为nil,调用方法、下标、属性失败,结果为nil

如果可选项不为nil,调用方法、下标、属性成功,结果会被包装成可选项

如果结果本来就是可选项,不会进行再次包装

判断方法有没有调用成功:

if let age = person?.age() { // ()?
    print("调用age成功", age)
} else {
    print("调用age失败")
}

形成可选链:

多个?可以链接在一起

如果链中任何一个节点是nil,那么整个链就会调用失败,可选链应用的地方还是很多的,在OC里面我们通常会加很多判断以避免崩溃,在Swift里面,因为有了可选链会减少很多我们自己的判断,提高了安全性。

var dog = person?.dog // Dog?
var weight = person?.dog.weight // Int?
var price = person?.car?.price // Int?
var scores = [
    "Jack" : [86, 82, 84],
    "Rose" : [79, 94, 81]
]
scores["Jack"]?[0] = 100
scores["Rose"]?[2] += 10
scores["Kate"]?[0] = 88
var num1: Int? = 5
num1? = 10 // Optional(10)
var num2: Int? = nil
num2? = 10 // nil
var dict: [String : (Int, Int) -> Int] = [
    "sum" : (+), //两个Int类型相加,返回一个Int类型
    "difference" : (-)
]
var result = dict["sum"]?(10, 20) // Optional(30), Int?

到此这篇关于Swift初始化器与可选链的使用方法介绍的文章就介绍到这了,更多相关Swift初始化器与可选链内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Swift中初始化init的方法小结

    前言 我们在深入初始化方法之前,不妨先再想想Swift中的初始化想要达到一种怎样的目的. 其实就是安全.在Objective-C中,init方法是非常不安全的:没有人能保证init只被调用一次,也没有人保证在初始化方法调用以后,实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的话,还可能会造成各种问题.虽然Apple也明确说明了不应该在init中使用属性来访问,但这并不是编译器强制的,因此还是会有很多开发者犯这样的错误. 所以Swift有了超级严格的初始化方法.一方面,Swift强

  • Swift编程中的初始化与反初始化完全讲解

    初始化 类,结构和枚举当 Swift 声明后准备初始化类实例.初始值被初始化为存储属性,并且新的实例的值也被进一步进行初始化.创建初始化函数的关键字是通过 init() 方法.Swift 初始化不同于 Objective-C,它不返回任何值.其作用是检查新创建的实例的其处理前初始化.Swift 还提供了"反初始化"过程中执行的内存管理操作当实例被释放. 对于存储的属性初始化器的作用 存储的属性处理实例之前初始化类和结构的实例. 存储属性使用初始分配和初始化值,从而消除了需要调用属性观察

  • Swift初始化方法的使用介绍

    目录 初始化 初始化器 初始化器的相互调用 两段式初始化 安全检查 重写 自动继承 初始化 初始化器 1.类.结构体.枚举都可以定义初始化器 class Size { init(age: Int) { } } var s = Size(age: 10) 2.类有2种初始化器:指定初始化器(deaignated initializer).便捷初始化器(convenience initializer) class Size { //指定初始化器 init(age: Int) { } //便捷初始化器

  • Swift中初始化方法的顺序介绍

    与 Objective-C 不同,Swift 的初始化方法需要保证类型的所有属性都被初始化.所以初始化方法的调用顺序就很有讲究.在某个类的子类中,初始化方法里语句的顺序并不是随意的,我们需要保证在当前子类实例的成员初始化完成后才能调用父类的初始化方法: 复制代码 代码如下: class Cat {     var name: String     init() {         name = "cat"     } } class Tiger: Cat {     let power

  • Swift中类与结构的初始化示例解析

    目录 一,结构的初始化 二,结构的初始化 三,结构中初始化错误示例 四,结构中init可以通过self关键字调用其他的init 五,类初始化错误示例 六,类的(Designated init)初始化器 七,Designated init 八,类的便利(convenience)初始化器 九,子类的专门初始化器 前言:通过学习与研究swift3.0的官方文档关于初始化这部分可以总结为一句话:类与结构是确保一个类型的实例可以使用之前,其所有存储属性都得到了正确的赋值. 一,结构的初始化 struct

  • Swift初始化器与可选链的使用方法介绍

    目录 初始化器 required 属性观察器 可失败初始化器 反初始化器(deinit) 可选链(Optional Chaining) 初始化器 required 用required修饰指定初始化器,表明其所有子类都必须实现该初始化器(通过继承或者重写实现) 如果子类重写了required初始化器,也必须加上required,不用加上override class Person { required init() {} init(age: Int) {} } class Student: Pers

  • 深入解析Swift语言编程中的可选链

    查询,调用属性,下标和方法上的一个可选可能 'nil' 的过程被定义为可选的链.可选链返回两个值 如果可选包含一个值,然后调用其相关属性,方法和下标返回值 如果可选包含一个"nil"值,所有的相关属性,方法和下标返回nil 由于多种查询方法,属性和下标故障组合在一起,以一种链将影响到整个链,并导致产生 'nil' 的值. 可选链作为一种替代强制解包裹 可选链与可选值后指定"?"调用一个属性,方法或下标当可选的值返回一些值. 程序用于可选链 '!' 复制代码 代码如下

  • js 可选链操作符的使用

    前言 可选链操作符(?.)允许读取位于链接对象链身处的属性的值,而不必明确验证链中的每个引用是否有效.不同之处在于,在引用为空(null或者undefined)的情况下不会引起错误,该表达式短路返回值是undefined.与函数调用一起使用时,如果给定的函数不存在,则返回undefined. 当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式根更短.更简明.在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的. 可选链操作符(?.) 语法 obj?.prop

  • axios 拦截器管理类链式调用手写实现及原理剖析

    目录 axios库的拦截器使用 整体设计 拦截器管理类实现 接口定义 代码实现 链式调用实现 axios库的拦截器使用 我们知道axios库的拦截器的使用方式如下: // 添加一个请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前可以做一些事情 return config; }, function (error) { // 处理请求错误 return Promise.reject(error); }); // 添

  • Effective C# 使用成员初始化器而不是赋值语句

    一般情况下,一个类都会有多个构造函数.随着时间的推移,成员变量.构造函数不断增加.为了处理这种情况最方便的办法就是:在声明变量的时候进行初始化,而不是在每个构造函数中进行.无论是类成员(静态变量)合适实例变量,我们都应该充分利用初始化器的语法. C#编程在,一般在声明一个变量的同时我们会对其进行初始化: 复制代码 代码如下: 1 class Employee 2 { 3 private List<Employee> empList = new List<Employee>(); 4

  • C#特性-对象集合初始化器介绍

    C# 3.0为你提供了对象集合初始化器: /// <summary> /// 图书类 /// </summary> public class Book { /// <summary> /// 图书名称 /// </summary> public string Title { get; set; } /// <summary> /// 单价 /// </summary> public float Price { get; set; }

  • c# 9.0新特性——模块初始化器

    作者:MarkKang 出处:https://www.cnblogs.com/markkang/ 1 背景动机 关于模块或者程序集初始化工作一直是C#的一个痛点,微软内部外部都有大量的报告反应很多客户一直被这个问题困扰,这还不算没有统计上的客户.那么解决这个问题,还有基于什么样的考虑呢? 在库加载的时候,能以最小的开销.无需用户显式调用任何接口,使客户做一些期望的和一次性的初始化. 当前静态构造函数方法的一个最大的问题是运行时会对带有静态构造函数的类型做一些额外的检查.这是因为要决定静态构造函数

  • SpringBoot深入浅出分析初始化器

    如有错误,望指正: SpringBoot可以有三种方式定义初始化器,来为容器中增加自定义的对象,具体如下: 1.定义在spring.factories文件中,被SpringFactoriesLoader发现注册: 在resources下建立META-INF文件夹,新建spring.factories文件,添加自定义的初始化器:org.springframework.context.ApplicationContextInitializer=com.mooc.sb2.initializer.Ini

  • C#自定义集合初始化器

    对int类型集合初始化,这样写: static void Main(string[] args) { var list = new List<int> {0, 1}; foreach (var item in list) { Console.WriteLine(item); } Console.ReadKey(); } 对键值对集合初始化,这样写: static void Main(string[] args) { var dic = new Dictionary<string, str

随机推荐