swift之kvc

===========kvc

KVC是OC特有的,KVC本质上是在运行时,动态向对象发送setValue:ForKey:方法,为对象的属性设置数值

因此,在使用KVC的方法之前,需要确保对象已经被正确实例化

在Swift中,如果属性是可选的,在初始化时,不会为该属性分配空间。

在OC中,基本数据类型就是保存一个值,不存在可选的概念

所以我们需要给可选的基本数据类型设置一个初始值,否则使用KVC就会报错。

如果想要在Swift中使用KVC,这个类必须要继承自NSOject,因为KVC是OC的东西。


KVC函数的调用顺序:

setValuesForKeysWithDictionary会按照字典中的key重复调用setValue:ForKey:函数

在重复调用的过程中,如果发现字典中对应的key在类中没有对应的属性,就会调用setValue:forUndefinedKey:函数去处理这个情况。如果没有实现setValue:forUndefinedKey:函数时,会抛出NSUndefinedKeyException,程序崩溃

所以应该根据具体的项目需求,来实现setValue:forUndefinedKey:函数

如果父类实现了setValue:forUndefinedKey:,子类不必再次实现这个方法了。


在 Swift 中想要兼容 KVC,需要该类继承 NSObject。下面是 KVC 中常用的几个方法:


根据传入的 key,设置 value:

func setValue(_ value:Any?, forKey key:String)


根据传入的 keyPath,设置 value,keyPath 即键路径可利用 . 遍历至键:

func setValue(_ value:Any?, forKeyPath keyPath:String)


根据传入的字典,设值,如果字典中有对象不存在的属性,则会抛出异常:

func setValuesForKeys(_ keyedValues: [String :Any])


当为不存在的某个键设值时,默认调用该方法抛出 NSUndefinedKeyException 异常,子类可重写该方法:

func setValue(_ value:Any?, forUndefinedKey key:String)


设置特定键的值为 nil 时,默认调用该方法抛出 NSInvalidArgumentException,子类可重写该方法(注:官方称该方法针对标量值(scalar value),例如整型和浮点型)对于其他类型没有提到,在 Demo 中有详细的列出是否支持):

func setNilValueForKey(_ key:String)


返回传入指定键的对应值:

func value(forKey key: String) -> Any?


返回传入指定键路径的对应值:

func value(forKeyPath keyPath: String) -> Any?


返回传入未定义的键路径的对应值:

func value(forUndefinedKey key: String) -> Any?


=====================kvc字典转模型===============================================


*****第一层模型

import UIKit


class LYBHomeLunboModel: NSObject {

    @objc var name:String?="11" //swift4.0中要加上@objc,否则在外面调用不到

    

    @objc var age:NSNumber?

    @objc var phones:[LYBPhonesModel]?

 init(dict:[String:Any]) {

        super.init()

         setValuesForKeys(dict)

    }

    override func setValue(_ value:Any?, forKey key:String) {

        

        if key=="phones"{

            let temp = value as! [AnyObject]

                var resultArray = [LYBPhonesModel]()

                for dict in temp {

                resultArray.append(LYBPhonesModel(dict: dictas! [String :AnyObject]))

            

        }

            phones = resultArray

            return

                    }

        super.setValue(value, forKey: key)

    }

    override func setValue(_ value:Any?, forUndefinedKey key:String) {

    }

    

   

}

*****************第二层模型*********

import UIKit


class LYBPhonesModel: NSObject {

   @objc var name:String?

   @objc var number:String?

    

    init(dict: [String:AnyObject]) {

        super.init()

        

        setValuesForKeys(dict)

    }

    

    override func setValue(_ value:Any?, forKey key:String) {

        super.setValue(value, forKey: key)

    }

    override func setValue(_ value:Any?, forUndefinedKey key:String) {

        

    }

}




*****************

//kvc

    func swiftkvc(){

     

 //1.这是一个JSON字符串

        let jsonStr ="[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"

        

        //2.吧JSON字符串变成data数据

        if let jsonData = jsonStr.data(using:String.Encoding.utf8, allowLossyConversion:false) {

          

    //***************系统的序列化成json*************

            do{

//                //3.吧jsondata转换成JSON对象(即字典,或字典数组)

                if  let dictArr:[[String:Any]]=(tryJSONSerialization.jsonObject(with:jsonData , options: .allowFragments)as?[[String :Any]])  {

                    let dict:[String:Any]=dictArr[1]

                    let model:LYBHomeLunboModel=LYBHomeLunboModel(dict:dict)

                    

                    print("\(model.phones![0].name!)")

                }

            }

        catch {


            }

        

    }


==================


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值