博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
swift之kvc
阅读量:4290 次
发布时间:2019-05-27

本文共 3165 字,大约阅读时间需要 10 分钟。

===========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 {

            }

        

    }

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

转载地址:http://rnmgi.baihongyu.com/

你可能感兴趣的文章
设计模式-策略模式(Strategy)
查看>>
设计模式-观察者模式(Observer)
查看>>
java浅拷贝(shallow clone)与深拷贝(deep clone)
查看>>
Elasticsearch-terms搜索及结果优化
查看>>
Elasticsearch-对一个field进行多值全文本搜索
查看>>
Elasticsearch-best_fileds和most_fields策略分析以及cross-fields弊端的解决
查看>>
Elasticsearch-近似搜索
查看>>
Elasticsearch-前缀、通配符、正则、模糊搜索详解
查看>>
Elasticsearch-搜索推荐
查看>>
java-nio之Selector组件
查看>>
java-编码解密
查看>>
netty源码分析之-Future、ChannelFuture与ChannelPromise详解(3)
查看>>
redis主从集群的搭建
查看>>
redis cluster集群搭建与深入分析(1)
查看>>
netty源码分析之-引导详解(4)
查看>>
redis cluster节点的添加与删除(2)
查看>>
nginx+redis+tomcat三级缓存架构讲解
查看>>
Reactor模式详解
查看>>
基于OpenRestry部署nginx+lua实现流量定向分发
查看>>
netty源码分析之-服务端启动核心源码分析(5)
查看>>