• Swift3.0-KVC构造函数与基本数据类型

    0.创建一个类:Person.swift

    //name属性是可选的,在需要的时候创建
    //在手机开发中,内存非常宝贵,实际运行中很多属性不一定需要分配空间
    var name: String?

    1.重写构造函数,用字典为本类设置初始值

    init(dict: [String: AnyObject]) {
    
        super.init()
        //使用 self 的方法 'setValuesForKeys' 之前,应该调用 super.initt(),否则会奔溃:Use of 'self' in method call 'setValuesForKeys' before super.init initializes self
        //KVC方法是 OC 的方法,在运行的时候给对象发送消息
        //执行'setValuesForKeys',首先要求对象已经实例化完成
        setValuesForKeys(dict)
    }

    1.1然在控制器中传值调用

    let p = Student(dict: ["name": "小明" as AnyObject])
    print(p.name)
    //打印输出: Optional("小明")

    2.在Person.swift中继续追加一个属性

    //给基本类型属性初始化
    //如果这样写:
    //var age: Int?
    //会抛出以下异常:
    //Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<******> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key age.'
    // - 意思是KVC会无法找到age的KEY,因为Int是一个基本数据类型的结构体
    //所以要这么写,赋初始值    
    var age: Int = 0

    2.1去控制器中传值调用

    let p = Student(dict: ["name": "小明" as AnyObject,"age": 18 as AnyObject])
    print("\(p.name) \(p.age)")
    //打印输出: Optional("小明") 18

    3.试图在Person.swift添加一个私有的属性

    //private var title: String?
    //直接报异常:Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<****** > setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key title.
    // - 如果是private属性,使用KVC设置的时候,程序会直接崩溃
    // - Swift中被Private修饰的属性或方法,彻底禁止外部访问,OC中私有属性或者方法可以通过runtime访问到,所以此时无法使用private修饰
    var title: String?

    3.1在控制器中打印输出

    let p = Student(dict: ["name": "小明" as AnyObject,"age": 18 as AnyObject,"title": "北京" as AnyObject])
    print("\(p.name) \(p.age) \(p.title)")
    //打印输出: Optional("小明") 18 Optional("北京")

    总结:

    1. 定义属性的时候,如果是对象,通常都是可选的(类后面加’?’)

    - 在需要的时候创建

    - 避免写构造函数,可以简化代码

    2. 如果是基本数据类型,不能设置为可选的,而且要设置初始值,否则KVC崩溃

    3. 若果需要使用KVC设置属性,属性不能是private的

    4. 使用KVC方法之前,应该调用 super.init 保证对象实例化完成

    展开全文
  • 我们都知道KVC 是OC NSobject特有的,之前在Swift4.0之前,继承NSobject的对象,可用动态的拿到字典调用KVC给模型赋值。只是比较省事的操作,有没有定义属性,只要从写UndefinedKey这个属性即可。  还是用代码演示...

     我们都知道KVC 是OC  NSobject特有的,之前在Swift4.0之前,继承NSobject的对象,可用动态的拿到字典调用KVC给模型赋值。只是比较省事的操作,有没有定义属性,只要从写UndefinedKey这个属性即可。

     还是用代码演示比如下面一个对象,从字典赋值

    //
    //  UserAccount.swift
    //  WeiBo
    //
    //  Created by 张宇 on 2018/2/6.
    //  Copyright © 2018年 张宇. All rights reserved.
    //
    
    //
    //  用户账号Model
    //
    
    import UIKit
    
    class UserAccount: NSObject {
        
        //MARK : 存储属性
        var  access_token:String = ""
        var  expires_in:TimeInterval = 0.0
        var  uid:String?
        
        init(dict:[String:Any]){
            super.init()
            setValuesForKeys(dict)
        }
        
        override func setValue(_ value: Any?, forUndefinedKey key: String) {
            
        }
        
        override var description: String{
            return  dictionaryWithValues(forKeys: ["access_token","expires_in","uid"]).description
        }
    }
    

    3.0这样写肯定是没有错误的,但是4.0的时候你就会发现一个问题forUndefinedKey这个方法每次都会调用,然后就崩溃了。


    猜测原因:这是因为KVC是OC 的方法,OC方法和属性都需要运行时写到类对象中,swift 利用KVC设置属性需要运行时机制,swift4.0以前,编译器默认帮我们做了在对象声明前加上了@objc,4.0需要手动加上。


      //MARK : 存储属性
        @objc var  access_token:String = ""
        @objc var  expires_in:TimeInterval = 0.0
        @objc var  uid:String?

       这样就不会报错了。



    展开全文
  • 在这里一定要记录下,因为在Swift中使用KVC,总是无法的找到Swift中创建的继承自NSObject类中的属性,每次执行的都是 override func setValue(_ value: Any?, forUndefinedKey key: String) { }原因是因为在...

    在这里一定要记录下,因为在Swift中使用KVC,总是无法的找到Swift中创建的继承自NSObject类中的属性,每次执行的都是

    override func setValue(_ value: Any?, forUndefinedKey key: String) {
            
        }
    原因是因为在Swift 4中继承 NSObject 的 swift class 不再默认全部 bridge 到 OC。也就是说如果我们想要使用KVC的话我们就需要加上@objcMembers 这么一个关键字。

    引用: 在 swift 3 中除了手动添加 @objc 声明函数支持 OC 调用还有另外一种方式:继承 NSObject。class 继承了 NSObject 后,编译器就会默认给这个类中的所有函数都标记为 @objc ,支持 OC 调用。苹果在Swift 4 中苹果修改了自动添加 @objc 的逻辑:一个继承 NSObject 的 swift 类不再默认给所有函数添加 @objc。只在实现 OC 接口和重写 OC 方法时才自动给函数添加 @objc 标识。

    所以我们在调用KVC的时候才不能被赋值。因为KVC是OC的方法。

    展开全文
  • swift 4.0 kvc 赋值失败问题 需要在模型属性前加上 @objc ,以保证属性被添加到运行时方法列表 @objc var access_token:String = "" @objc var expires_in:TimeInterval = 0.0 @objc var ...
    1. swift 4.0   kvc 赋值失败问题  需要在模型属性前加上 @objc ,以保证属性被添加到运行时方法列表
    2.   @objc var  access_token:String = ""  
    3.   @objc var  expires_in:TimeInterval = 0.0  
    4.   @objc var  uid:String?
    展开全文
  • ActivityModel *activityModel = [[ActivityModel alloc] init];  [activityModel setValuesForKeysWithDictionary:temp]; //KVC赋值  [self.dataArray addObject:activityModel]; 需要注意的是 KVC赋值的时候


    KVC 详解 http://www.2cto.com/kf/201507/415647.html


     ActivityModel *activityModel = [[ActivityModel alloc] init];

            [activityModel setValuesForKeysWithDictionary:temp];  //KVC赋值
            [self.dataArray addObject:activityModel];

    需要注意的是 KVC赋值的时候  所创建model模型里面的属性必须和KVC字典里的key值相对应

         如果model里面的属性可以是不属于比KVC的字典的key 


    但是kvc里面的key 如果在model里面没有对应的属性,model必须重写方法

      -(void)setValue:(id)value forUndefinedKey:(NSString *)key{}

    不写的话 会报错
        setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key image_hlarge.

    为了实现对嵌套json的处理,(后者自定义key的赋值方法)我们需要重写-(void)setValue:(id)value forKey:(NSString *)key方法

    例子:见最后

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

    KVO

    只要对被观察者被重新赋值 就会走观察方法 不管所赋的值是否变化

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        
        NSLog(@"%@",keyPath);
        NSLog(@"%@",object);
        NSLog(@"%@",change);
        NSLog(@"%@",context);
        
        //1.取值
        id new = [object valueForKeyPath:keyPath];
        NSLog(@"%@",new);

       //2.取值
        id new1 = [change objectForKey:NSKeyValueChangeNewKey];
        NSLog(@"new1---%@",new1);
    }

    // KVC 赋值例子

    @interface DetailModel :NSObject

    @property (nonatomic,copy)NSString *name;

    @property (nonatomic,copy)NSString *objectId;

    @property (nonatomic,copy)NSString *userId;

    @property (nonatomiccopyNSString *createdAt;

    @property (nonatomic,copy)NSString *headerImage;

    @property (nonatomicassignNSNumber *age;

    @implementation DetailModel

    -(void)setValue:(id)value forUndefinedKey:(NSString *)key { 

    }

    -(void)setValue:(id)value forKey:(NSString *)key {

        if ([keyisEqual:@"headerImage"]) {

    // 自定义 headerImage的赋值 因为headerImage 在返回中是个字典,而有用的只要url

            _headerImage = [valueobjectForKey:@"url"];

        } else {

            [supersetValue:valueforKey:key];

        }

    }

    -(NSString*)description;


    JSON: 

     {

        age = 20;

        createdAt = "2015-09-17T02:40:45.219Z";

        headerImage =     {

            "__type" = File;

            bucket = sNkArza7;

            createdAt = "2015-09-17T10:48:35.621Z";

            key = "KsjzUhNAdymW0FNjcxEgR3D.png";

            metaData =         {

                "_checksum" = 121f6ec8713bfd3a7c6143fb2a0f5d4d;

                owner = 55fa1da860b232fc2abc51d7;

                size = 2369719;

            };

            "mime_type" = "image/png";

            name = "avatar.png";

            objectId = 55fa9a83ddb2e44a4844974c;

            updatedAt = "2015-09-17T10:48:35.621Z";

            url = "http://ac-sNkArza7.clouddn.com/KsjzUhNAdymW0FNjcxEgR3D.png";

        };

        name = "\U660e\U661f";

        objectId = 55fa282d60b25f2389575a49;

        updatedAt = "2015-09-17T10:48:38.259Z";

        userId = 55fa1da860b232fc2abc51d7;

    }

    DetailModel *model = [[DetailModelalloc]init];

     [model setValuesForKeysWithDictionary:responseObject];

    NSLog(@"%@", model);

     userId: 55fa1da860b232fc2abc51d7,

     name: 明星

     objectId: 55fa282d60b25f2389575a49, 

     age: 20, 

     creat: 2015-09-17T02:40:45.219Z, 

     _headerImage: http://ac-sNkArza7.clouddn.com/KsjzUhNAdymW0FNjcxEgR3D.png





    展开全文
  • KVC简单介绍 KVC是OC特有的,KVC本质上是在运行时,动态向对象发送setValue:ForKey:方法,为对象的属性设置数值 因此,在使用KVC的方法之前,需要确保对象已经被正确实例化 在Swift中,如果属性是可选的,在初始...
  • swift中使用kvc赋值的时候。假如给基础数据类型赋值,必须先给基础数据类型的变量一个初始值。 否则将会报错。 var id : Int = 0 setValue(dict["id"], forKey: "id") 转载于:...
  • Swift 反射Mirror的使用

    2020-01-02 19:47:29
    反射(Reflection)介绍 对于C#、Java开发人员来说,肯定都对反射这个概念相当熟悉。所谓反射就是可以动态...hibernate的属性映射就是通过反射来赋值的,spring的bean的创建就是根据配置的class来反射构建的。 ...
  • kvc为什么可以给readOnly赋值 oc中的readonly不是严格意义上的只读,他的意思是不能修改名字 oc的类可以使用KVC赋值,而swift不能使用KVC赋值,不能值调用get方法 uibutton 是oc类的
  • SwiftKVC的使用

    2019-01-23 11:29:22
    Swift中使用KVC分为3中情况: 1、在swift3.0之前,类必须要继承自NSObject,因为KVC是OC的东西 2、在Swift4.0之后,类必须要继承自NSObject,同时还需要在属性前面加上@objc 在Swift4.0之前,编译器会默认帮我们在对象...
  • 利用KVC的来简化抽取出控件设置style的代码,想达到一个css的效果。这个库用swift编写,使用起来大概这样: class ViewController: UIViewController { var tableView: UITableView? override func viewDidLoad...
  • 1.命名空间 在同一个项目中,所有的类都是共享的,可以直接访问,...Swift支持函数重载,所有构造函数都是init 作用: 分配空间,设置初始值 ** 注意 Object-c的初始化,是从类继承关系链,从父类开始逐级向子类初始化...
  • 参考swift4.0字典转模型:...=====================kvc字典转模型========================= *****第一层模型 import UIKit class LYBHomeLunboModel: NSObject {  @...
  • KVC的使用

    2017-08-27 11:28:09
    KVC: Key Value Coding(键值编码) KVC的作用有哪些? 最常用于取值和赋值 利用KVC进行简单赋值 /** * 利用KVC进行简单赋值 */ void test(){ HYRPerson *person = [[HYRPerson alloc] init]; // 常规赋值 /* ...
  • iOS开发中很多人都知道KVC ,聊到KVC大家也都知道,就是字典转模型,但是再具体聊的话,就说不太清楚了,这篇文章,准备把KVC再来了解一下; XZPerson *person = [XZPerson alloc]; person.name = @"Alan"; 在...
  • swift KVC笔记

    2019-06-21 15:24:58
    class myModel: NSObject { // MARK:- 定义属性 var name : String = "" var url : String = "" // MARK:- 自定义构造函数 override init() { ... init(dict : [String : Any]) { super....
  • swift: 方法的重载/重写/KVC构造函数
  • Swift中的反射 在Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect)。当然,目前Swift中的反射还没有其他语言中的反射功能强大,不仅远不及OC的Runtime,离Java的反射也有一定的距离。Swift的反射...
  • 在OC中,我们有很多优秀的第三方库帮助我们实现,比如MJExtension、JSONModel等,这些库基本都是利用runtime实现读取属性名并利用kvc重新赋值属性。 在Swift中,由于runtime的局限,比较出名的有SwiftyJSON、...
1 2 3 4 5 ... 20
收藏数 663
精华内容 265