- 构造函数
- 非 Optional 属性, 都必须在构造函数中设置初始值, 从而保证对象在实例化的时候, 属性都能被正确的初始化
- 构造函数的目的: 给自己的属性分配空间并且设置初始值
- 在调用父类的构造函数之前, 必须保证本类的属性都已经完成初始化
- 调用父类的构造函数, 给父类的属性分配空间并且设置初始值
- 如果重载了构造函数, 并且没有重写父类的 init 方法,系统不再提供 init 构造函数(默认是会有的), 因为默认的构造函数, 不能给本类的属性分配空间
// Person 类没有 '初始化器's, 构造函数可以有多个, 默认是 initclass Person: NSObject
{
var name: String
// 重写: 父类有这个方法, 子类重新实现, 需要 override 关键字
override init()
{
// 给 self.name 初始化: 分配空间, 设置初始值
name = "AAA"
super.init()
}
// 重载: 函数名相同, 会是参数和个数不同
// 重载可以给自己的属性从外部设置初始值
init(name: String)
{
// 使用参数的 name 设置属性
self.name = name
// 调用父类型的构造函数
super.init()
}
}
- KVC 构造函数
- 在设置模型的时候, 如果是对象, 通常是可选的, 在需要的时候创建, 避免写构造函数, 可以优化代码
- 如果是基本数据类型, 不能设置成可选的, 而且要设置初始值, 否则 KVC 会崩溃
- 如果需要使用 KVC 设置属性值, 属性不能是 private 的
- 在使用 KVC 方法之前, 应该调用 super.init 方法, 保证对象被完全初始化
- 如果子类没有重写父类的方法, 调用的时候, 会直接调用父类的方法
class Person: NSObject
{
// name 属性是可选的, 在 OC 中很多的属性都是在需要的时候创建的
// 例如 vc.view / tableViewCell.textLabel / detailLabel / imageView
//延迟加载:在需要的时候再创建
var name: String?
// 给基本数据类型初始化
// var age: Int? 当使用 KVC 会提示无法找到 age 的 KEY
//原因: Int是一个基本数据类型的结构体, OC中只有基本数据类型
var age: Int = 0
// 如果是 private 属性, 使用 KVC 设置值的时候, 同样无法设置
// 如果设置成 private 属性 / 方法, 禁止外部访问的
// private var title: String?
init(dict: [String : Any])
{
// 保证对象已经完全初始化完成
super.init()
// 使用 self 的方法 setValuesForKeys 之前, 应该调用 super.init()
// KVC的方法,是OC的方法,在运行时给对象发生消息,要求对象已经实例化完成
setValuesForKeys(dict)
// super.init()
}
// 重写父类的方法
override func setValue(_ value: Any?, forUndefinedKey key: String)
{
// 设置 调用 super, 将父类的代码实现完全覆盖, 防止键值对不匹配时的崩溃
}
}
- 便利构造函数
- 便利构造函数允许返回 nil, 正常的构造函数一定会创建对象
- 便利构造函数的目的: 判断给定的参数是否符合条件, 如果不符合条件, 返回 nil, 不会创建对象, 减少内存的开销
- 只有便利构造函数中使用 self.init 来构造当前对象; 没有 convenience 关键字的构造函数是负责创建对象的, 反之是用来检查条件的, 本身不负责对象的创建
- 如果要在便利构造函数中使用当前对象的属性, 一定要在 self.init 之后
- 便利构造函数不能被重写, 或者调用 super
class Student: NSObject
{
var name: String?
var age: Int = 0
// 便利构造函数
convenience init?(name: String, age: Int)
{
if age > 100
{
return nil
}
// 使用 self 访问 name 之前, 应该调用 self.init
// self.name = name
// 实例化当前对象
self.init()
// 执行到此 self 才允许被访问, 才能访问对象的属性
self.name = name
}
}
- 析构函数
- 跟踪对象的销毁
- 没有 func 不让外面调用
- 没有 () 不让重载
- 在对象被销毁前调用
- 类似于 OC 的 dealloc
deinit
{
/*
1.跟踪对象的销毁
2.必须释放
-通知, 不释放不会崩溃, 但是会造成内存泄露
- KVO,不释放会崩溃
- NSTimer / CADisplayLink
*/
}