类的构造函数介绍
构造函数类似于OC中的初始化方法:init
默认请情况下实例化一个类时,比如会调用一个初始化函数
即便没有编写任何构造函数,编译器也会提供一个默认的构造函数
如果是继承自NSObject的类,可以对父类的构造函数进行重写
构造函数的基本使用
类的属性必须有值;
如果不是在定义时初始化值,可以在改造函数中赋值
1.重写
//: Playground - noun: a place where people can play
import UIKit
class Person: NSObject {
var name: String?
var age: Int = 0
// 父类存在init(),重写需要在前面加override
override init() {
// 在构造函数中,如果没有明确的调用super.init(),系统也会调用
// 但建议自己调用
super.init()
print("init")
}
}
let p = Person()
let p = Person() 实例化类就会调用init() 方法
2.如何在实例化类的同时传入参数给属性赋值,类似OC中的 -(instanceType)initWithName:(NSString *)name age:(int)age; ?
这时就需要自定义构造函数:
// 自定义构造函数
init(name: String, age: Int) {
// 保存
self.name = name
self.age = age
}
这样就可以在实例化类的时候传入name和age:
// 实例化
let p1 = Person(name: "jack", age: 18)
// 获取
print(p1.age) //18
if let age = p1.name {
print(age) //jack
}
3.传入字典创建对象
类似OC中的-(instanceType)initWithDict:(NSDictionary *)dict;
init(dict: [String: AnyObject]) {
// 因为根据键在字典里取值,不一定都能取到值,所以dict["name"]是可选类型
// 此处是AnyObject?
self.name = dict["name"] as? String
//self.age = dict["age"] as! Int
//这样写法有 强制解包 的风险,应该用可选绑定的方式
if let age = dict["age"] as? Int {
self.age = age
}
}
let p2 = Person(dict: ["name":"lily", "age":20])
print(p2.age) //20
if let age = p2.name {
print(age) //lily
}
4.KVC要注意的点
上面可以通过KVC的方式赋值:
init(dict: [String: AnyObject]) {
// 必须先调用super
super.init()
setValuesForKeysWithDictionary(dict)
}
但这样可能会有什么问题呢?
比如 let p2 = Person(dict: ["name":"lily", "age":20,"weigth":60]) 就会报错:
控制台打印:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__lldb_expr_297.Person 0x7f8b30531f90> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key weigth.'
*** First throw call stack:
这样我们的类中没有weigth 这个属性,KVC赋值的时候找不到这个key。
解决方法:
// KVC时重写这个方法
override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
本文深入介绍了Swift语言中构造函数的概念及使用方法,包括默认构造函数、重写父类构造函数、自定义构造函数以及通过字典创建对象的过程,并讨论了使用KVC时需要注意的问题。
1940

被折叠的 条评论
为什么被折叠?



