程序员

Swift-构造函数,构造函数与KVC

2017-09-08  本文已影响160人  逾期的誓言
timg.jpg 淘劵吧
  • 构造函数类似于OC中的初始化方法:init方法
  • 默认情况下载创建一个类时,必然会调用一个构造函数
  • 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数。
  • 如果是继承自NSObject,可以对父类的构造函数进行重写

创建Person类 继承NSObject

  1. 声明Name 属性
class Person: NSObject {
    // 1,声明name 属性 会报错:(Class 'Person' has no initializers (Person类没有初始化器 默认是init))
    var name: String
}
  1. 调用默认初始化器
class Person: NSObject {
   // 1,声明name 属性 会报错:(Class 'Person' has no initializers (Person类没有初始化器 默认是init))
   var name: String
   
   // 2 ,调用默认的初始化器 会报错:(Property 'self.name' not initialized at implicitly generated super.init call(在调用父类 构造函数之前,self.name 没有被初始化))
   override init() {
       print("-----------------Person init()-----------------")
       super.init()
   }
}
  1. 给name赋值
class Person: NSObject {
    // 1,声明name 属性 会报错:(Class 'Person' has no initializers (Person类没有初始化器 默认是init))
    var name: String
    
    // 2 ,调用默认的初始化器 会报错:(Property 'self.name' not initialized at implicitly generated super.init call(在调用父类 构造函数之前,self.name 没有被初始化))
    override init() {
        //3,Property 'self.name' not initialized at super.init call (提示 self.name 初始化 分配空间,设置初始值)
        // 所以在 super.init() 之前 给name 赋值 
        name = "iOSCodeZhao"
        print("-----------------Person init()-----------------")
        super.init()
    }
}

实例化Person 调用构造函数

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let person = Person();
        print(person.name)
    }
}

重写,重载

重写:父类有这个方法,子类重新实现 需要 override 关键字 如: override func viewDidLoad() {}

重载: 函数名相同 但是参数和个数不同,重载可以给自己的属性从外部设置初始值, OC没有重载,仅有initWith xxx 自定义初始化方法; 如果重载了构造函数,并不没有实现父类 init 方法,系统不再提供init() 构造函数默认是有的

class Person: NSObject {
    var name: String
    
    // 重写
    override init() {
        print("Person init")
        name = "赵师顺"
        super.init()
    }
    //重载
    init(name: String) {
        self.name = name;
        super.init()
    }
}

调用Person的重载

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 调用系统 构造函数
        let person = Person();
        print(person.name)
        // 重载
        let p = Person(name: "隔壁老王")
        print(p.name)
    }
}

控制台输出结果

屏幕快照 2017-09-08 下午4.10.54.png

构造函数与KVC

注意事项:
1,定义模型属性的时候,如果是对象,通常都是可选的
2, 如果是基本数据类型不能设置成可选的,而且要设置初始值
3,使用KVC 方法之前 应该调用 super.init()
4,如果使用KVC 设置数值,属性不能是private 的

class Person: NSObject {
    // 在OC中很多属性都是在需要的时候创建
    // 因为在手机开发,内存宝贵,有些属性并不一定需要分配空间
    // 延迟加载,在需要的时候在创建
    var name: String?
    // 给基本数据类型做初始化
    var age = 0
    // 如果是Private 私有属性,使用KVC设置值的时候,同样无法设置
    // 如果设置成private  禁止外部访问
    private var title: String?
    
    // 重载构造函数,使用字典为本类设置初始值
    init(dict: [String: AnyObject]) {
        super.init()
        // Use of 'self' in method call 'setValuesForKeys' before super.init initializes self(在使用setValuesForKeys之前 调用 super.init)
        //  KVC 方法是 OC方法,特点就是在运行时给对象发送消息
        // 所以要求 对象已经实例化完成  而且name 是个可选值 所以        super.init() 放在前面
        setValuesForKeys(dict)
    }
}

调用

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let p  = Person(dict: ["name": "肇事顺" as AnyObject])
        print(p.name ?? "")
    }
}
上一篇下一篇

猜你喜欢

热点阅读