Swift学习笔记九:类 Class

  • 构造函数
    • 非 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
        */
    }

 

posted @ 2017-02-18 15:12  小小聪明屋  阅读(248)  评论(0编辑  收藏  举报