Swift学习笔记15——初始化(Initialization)和析构(Deinitialization)其二
2015-10-05 15:55
543 查看
可失败的构造器(Failable Initializers)
Swift中有个概念,就是创建实例的时候如果条件不符合,可以返回一个nil对象。这类可以返回nil的构造器叫做可失败的构造器。语法是在init的前面加上一个?。当条件不满足的时候,你可以用 return nil结束构造方法。那么这时候得到的实例其实是一个nil,这里也说明了,可失败构造器返回的是可选类型。其实之前也说过,Swift的构造器是不需要返回值的。所以你成功的时候不需要写return什么东东。
值类型的可失败构造器
下面是structure的。
接下来是枚举类的,
对应有默认值的枚举类,会自动生成一个init?(rawValue:)的构造器。如下
类的可失败构造器
有一个规则,就是必须在本类所有的属性(包括继承的)都赋值之后才可以返回nil
可失败初始化的传递过程
一个可失败的构造器可以调用其他的构造器,无论是可失败的还是不会失败的。
但是一个不可失败的构造器不能去调用一个可失败的构造器。如果去调用父类的可失败构造器,虽然用解包可以解决,但是一旦父类的可失败构造器返回了nil,那么程序直接崩溃。
同样的,可失败的构造器也可以被重写,你可以重写为不可失败的构造器。
但是不可失败的构造器不能覆盖为可失败的构造器。
你可以用!代替?来实现可失败构造器,那么这样得到的实例会自动解包。当然,存在nil报错的问题。记得处理。
必须构造器(Required Initializers)
在构造器前面加上required关键字就行了。这样的构造器要求子类必须重写。子类重写这个构造器的时候,也必须加上required关键字。要求子类的子类也要重写这个构造器。
写了required后不用写override关键字。写了会有警告。
给属性默认值时使用闭包或函数
析构器
析构器,就是在一个实例再也不用到时候调用的方法。析构器里面完成一些清理工作或保存数据等等。析构器是系统自动调用的,不允许自行调用。
语法
那么什么时候才是一个实例再也不需要?这个将在下篇文章自动引用计数(ARC)里面讲。
Swift中有个概念,就是创建实例的时候如果条件不符合,可以返回一个nil对象。这类可以返回nil的构造器叫做可失败的构造器。语法是在init的前面加上一个?。当条件不满足的时候,你可以用 return nil结束构造方法。那么这时候得到的实例其实是一个nil,这里也说明了,可失败构造器返回的是可选类型。其实之前也说过,Swift的构造器是不需要返回值的。所以你成功的时候不需要写return什么东东。
值类型的可失败构造器
下面是structure的。
struct Apple { var pricePerKg: Double init?(pricePerKg: Double){ if pricePerKg < 0 { return nil } self.pricePerKg = pricePerKg } } print(Apple(pricePerKg: 2)) print(Apple(pricePerKg: -2)) //打印 //Optional(SwiftTest.Apple(pricePerKg: 2.0)) //nil
接下来是枚举类的,
enum FruitSet { case apple, orange, banana init?(symbol: Character){ switch symbol { case "a","A" : self = .apple case "o","O" : self = .orange case "b","B" : self = .banana default : return nil } } } print(FruitSet(symbol: "a")) print(FruitSet(symbol: "e")) //打印 //Optional(SwiftTest.FruitSet.apple) //nil
对应有默认值的枚举类,会自动生成一个init?(rawValue:)的构造器。如下
enum FruitSet : Character{ case apple = "a", orange = "o", banana = "b" } print(FruitSet(rawValue: "a")) print(FruitSet(rawValue: "e"))
类的可失败构造器
有一个规则,就是必须在本类所有的属性(包括继承的)都赋值之后才可以返回nil
class Apple { var pricePerKg: Double init?(pricePerKg: Double){ if pricePerKg < 0 { return nil //这句报错,所以你必须先初始化其他属性值 } self.pricePerKg = pricePerKg } }
可失败初始化的传递过程
一个可失败的构造器可以调用其他的构造器,无论是可失败的还是不会失败的。
但是一个不可失败的构造器不能去调用一个可失败的构造器。如果去调用父类的可失败构造器,虽然用解包可以解决,但是一旦父类的可失败构造器返回了nil,那么程序直接崩溃。
class Fruit { var name: String init?(name: String){ self.name = name if name.isEmpty { return nil } } } class Apple: Fruit { var pricePerKg: Double init(pricePerKg: Double){ self.pricePerKg = pricePerKg super.init(name: "")! //利用解包调用了父类的可失败构造器,但是因为这样父类会返回一个nil,所以程序在这行会崩溃 } convenience init?(){ self.init(pricePerKg: 3) } } var i = Apple(pricePerKg: 3)
同样的,可失败的构造器也可以被重写,你可以重写为不可失败的构造器。
但是不可失败的构造器不能覆盖为可失败的构造器。
你可以用!代替?来实现可失败构造器,那么这样得到的实例会自动解包。当然,存在nil报错的问题。记得处理。
必须构造器(Required Initializers)
在构造器前面加上required关键字就行了。这样的构造器要求子类必须重写。子类重写这个构造器的时候,也必须加上required关键字。要求子类的子类也要重写这个构造器。
写了required后不用写override关键字。写了会有警告。
给属性默认值时使用闭包或函数
func getprice()->Double { return 1 } class Apple { var pricePerKg: Double = getprice() var name = { return "apple" }() //留意这对小括号,没有的话那就是给属性赋值一个闭包了。 } var a = Apple() print(a.pricePerKg,a.name)
析构器
析构器,就是在一个实例再也不用到时候调用的方法。析构器里面完成一些清理工作或保存数据等等。析构器是系统自动调用的,不允许自行调用。
语法
deinit { // perform the deinitialization }
那么什么时候才是一个实例再也不需要?这个将在下篇文章自动引用计数(ARC)里面讲。
相关文章推荐
- 「Swift学习笔记」使用UILabel显示多行文本
- swift 设计模式---委托(delegate)模式传值
- swift设计模式--观察者模式
- Swift学习笔记14——初始化(Initialization)和析构(Deinitialization)其一
- Swift Mailer ——Comprehensive mailing tools for PHP
- swift页面传值之block(闭包)传值
- Swift学习笔记13——类继承(Inheritance)
- Swift语法之 guard
- [swift]监测iphone自由落体动作
- Swift过程控制和功能
- Swift学习笔记12——下标(Subscripts)
- Swift学习笔记11——方法(Method)
- Swift学习笔记10——属性(Properties)
- Swift 线程
- Swift 2.0 之map 与 zip
- Swift学习笔记9——类和结构体(Classes and Structures)
- Swift学习- 继承(十三)
- Swift学习笔记8——枚举类(Enumerations)
- swift map
- 【面试必备】Swift 面试题及其答案