Swift 4 构造函数,便利构造函数与KVC及运行时访问属性小结

本文总结了Swift中的构造函数、便利构造函数以及KVC的相关知识,包括构造过程、函数重载与重写、KVC在Swift中的应用,以及Swift 4运行时如何获取类的属性列表。强调了构造过程中属性初始化的顺序,以及KVC在处理可选属性时的注意事项。
摘要由CSDN通过智能技术生成

1.命名空间

  • 在同一个项目中,所有的类都是共享的,可以直接访问,不用import
  • 不同的项目中有相同的类,是可以共存的

2.构造函数

  • 是一种特俗的函数
  • 主要用来在创建对象时,初始化对象
  • 给对象的成员变量设置初始值
  • Swift支持函数重载,所有构造函数都是init
  • 作用: 分配空间,设置初始值

** 注意

  • Object-c的初始化,是从类继承关系链,从父类开始逐级向子类初始化
  • Swift的初始化,是先从子类开始,逐级向父类初始化

  • 非optonal属性,都必须在构造函数中设置初始值,从而保证对象再被实例化的时候,属性都被正确地初始化

  • 在调用父类构造函数之前,必须保证本类的属性已经完成初始化
  • Swift中的构造函数不用写func关键字

    1.构造函数的目的是: 给自己的属性分配空间并且设置初始值
    2.调用父类构造函数之前,需要先给本类的属性设置初始值
    3.调用父类的构造函数,给父类的属性分配空间并设置初始值
    4.如果重载了构造函数,并且没有实现父类的init方法,系统不再提供init函数(默认会提供的),
    5.默认的构造函数不能给本类的属性分配空间

3.重载与重写

重载: overload

  • 函数名相同
  • 参数类型和个数不同
  • 如果重载了构造函数,并没有实现父类的init方法,系统不再提供init()构造函数
  • 默认的init()构造函数,不能给本类的属性分配空间

重写: override

  • 父类中已存在此方法
  • 子类重新实现父类的方法
class ZYImage: NSObject {

    var name:String

    //重写
    override init() {
        name = "zhouyu"
        super.init()
    }

    //重载
    init(name: String) {
        self.name = name
        super.init()
    }
}

    override func viewDidLoad() {
        super.viewDidLoad()

        let image = ZYImage()
        print(image.name)

        let image2 = ZYImage(name: "wangwu")
        print(image2.name)
    }

4. KVC构造函数

要搞清一个问题

  • iOS开发中,很多类的属性都是需要用到的时候才创建的,所以是可选的
  • 定义模型属性时,如果是对象,通常是可选的: 需要的时候才创建,延迟加载,避免写构造函数 例如: var name: String?

KVC 是 OC 特有的,KVC 本质上是在运行时,动态向对象发送 setValue:ForKey: 方法,为对象的属性设置数值.
- 因此,在使用 KVC 方法之前,需要确保对象已经被正确实例化.
- 必选属性必须在调用父类构造函数之前完成初始化分配工作


  • 基本数据类型在Swift ,与KVC不兼容

如果基本数据类型为nil,KVC在调用 setValue(value: AnyObject?, forKey key: String) 找不到这个属性, 使用KVC时给基本数据类型设置初始值
import UIKit

class Person: NSObject {
    /// 姓名
    var name: String?
    /// 年龄
    var age: Int = 0

    /// `重写`构造函数
    ///
    /// - parameter dict: 字典
    /// - returns: Person 对象
    init(dict: [String: Any]) {
        super.init()
        setValuesForKeys(dict)
    }

    override func setValue(_ value: Any?, forKey key: String) {
        print("\(key) \(String(describing: value))")
    }

    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        print("\(key) \(String(describing: value))")
    }
}
let person = Person(dict: ["name": "zhouyu" ,"age": 28])

5.Swift 4.0运行时获取类的属性列表

import UIKit
//@objcMembers Swift 4.0后,必须写,运行时才能获取属性
@objcMembers class Person: NSObject {
    /// 姓名
    var name: String?
    /// 年龄
    var age: Int = 0
    /// 性别
    var sex: String?

    class func getClassPropertyList() -> [String] {
        var propertyList:[String] = []
        var count: UInt32 = 0

        //UnsafeMutablePointer<objc_property_t>?  数组
        let list = class_copyPropertyList(self, &count)

        for i in 0..<Int(count) {
            //objc_property_t
            guard let property = list?[i] else { continue }
            //UnsafePointer<Int8>   Int8-->Byte-->Char-->C语言的字符串
            let propertyCharName = property_getName(property)
            //C语言的字符串转Swift的String
            guard let propertyName = String(utf8String: propertyCharName)  else { continue }
            propertyList.append(propertyName)
        }

        free(list)
        return propertyList
    }
}
print(Person.getClassPropertyList())
//结果
["name", "age", "sex"]

1.基本数据类型,在OC中没有可选值这一说,如果定义成可选项,KVC获取不到,会崩溃
2.private修饰的属性,运行时同样获取不到此属性,也会是KVC崩溃
3.在Swift 4中继承 NSObject 的 swift class 不再默认全部 bridge 到 OC,如果想使用运行时获取类的细节,需要在class前面加上@objcMembers关键字。

6.便利构造函数

  • convenience关键字修饰init(), 可以返回nil
  • 只有便利构造函数中可以调用self.init()
  • 便利构造函数不能被重写和super
  • 用于条件检测和简化对象创建
  • 常用与UIKit中,使用类工厂方法快速创建类似的控件
    convenience init?(name: String, age: Int, sex: String) {
        //书写判断条件
        if age <= 0 {
            return nil
        }

        //MARK: 调用self.init
        self.init()

        //给属性赋值
        self.name = name
        self.age = age
        self.sex = sex
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值