`
ydbc
  • 浏览: 766736 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

ios开发之你真的了解了KVC吗?

 
阅读更多

之前一直以为自己了解KVC 其实只是井底之蛙啦,真正的要把KVC原原本本的说出来还真的不是一件简单的事情。于是今天写下这边文章,告诫自己要知其然还要知其所以然。

一.KVC的基本概念

Key-value coding,它是一种使用字符串标识符,间接访问对象属性的机制,而不是直接调用getter 和 setter方法。通常我们使用valueForKey 来替代getter 方法,setValue:forKey来代替setter方法。

下面是使用KVC 和 不使用 KVC的代码对比

Persion *persion =  [ [Persion alloc] init ];

//不使用KVC
persion.name = @"hufeng" ;

//使用KVC的写法
[persion  setValue:@"hufeng" forKey:@"name"];

看出区别来了吗?你可能会说 你写的太简单了,我们实际用的时候不可能有这样复杂的类,下面我们写个复杂点的:我们有一个人 这个人有一个手机类 这个手机类 有一个电池类 我们要获取这个电池类 比之前复杂了吧。

没有KVC

Persion *persion =  [ [Persion alloc] init ];

Phone *phone = persion.phone;

Battery *battery = phone.battery;

使用KVC

Battery *battery = [persion valueForKeyPath: @"phone.battery" ];

注意- valueForKeyPath 里面的值是区分大小写的,你如果写出Phone.Battery 是不行的

说到这里你可能会问 我能不能对 NSArray 调用KVC吗? 答案是否定的,因为array 没有keys啊,但是你可以对array里面的item 使用KVC。

KVC 最常用的还是在序列化和反序列话对象。我们经常需要把json字符串反序列化成我们想要的对象 下面是一个例子 将字典用NSKeyedArchiver 序列化成对象

- (id)initWithDictionary:(NSDictionary *)dictionary {

    self = [self init];

    if (self){

        [self setValuesForKeysWithDictionary:dictionary];

    }

    return self;

}

注意 这里有一个坑 当我们setValue 给一个没有定义的字典值(forUndefinedKey)时 会抛出NSUndefinedKeyException异常的 记的处理此种情况

还有一个需要注意的是KVC 并没有类型检验,毕竟Object-C 还是动态的啦。 还是看下面的代码吧

[persion setValue:[NSNumber numberWithInteger:1] forKey:@"name"]; 
// compiles and runs

persion.name = [NSNumber numberWithInteger:1]; 
// won't compile: Incompatible pointer types assigning to 'NSString *' from 'NSNumber *'

setValue forKey 得到的对象是泛型的id, 只有在使用的时候才能确定类型。你可能会问不至于吧 OC 这样弱啊,当然不是 OC 提供了了一个方法validateValue来解决这个问题

@property (nonatomic, strong) NSString name;

- (BOOL)validateName:(id*)ioValue error:(NSError**)error {
    // Validation logic goes here

}

Person *p = [Person new];

NSString *name = @"Jason Hu";

NSError *error = nil;


// This call below actually calls our validateName: error: method

if ([p validateValue:&name forKey:@"name" error:&error]) {

    [p setValue:name forKey:@"name"];
}

你可能会问写这样多代码 才只验证了一个属性 那如果我这个类有n+个属性 难道我要写n+个验证方法吗?


二.KVC 验证

到这里我们对KVC已经有了一个初步印象,到这里其实还只是冰山一角。
下面我们要提高更高的要求,如果让key 支持 不区分大小写

下面我们提到一个方法initialize

initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目或者类文件被引用进来,但是没有使用,那么initialize也不会被调用 ,到这里 知道我们接下来要干嘛了吧

+ (void)initialize {
    [super initialize];

    dispatch_once(&onceToken, ^{
        modelProperties = [NSMutableDictionary dictionary];
        propertyTypesArray = @[/* removed for brevity */];
    });
    NSMutableDictionary *translateNameDict = [NSMutableDictionary dictionary];
    [self hydrateModelProperties:[self class] translateDictionary:translateNameDict];
    [modelProperties setObject:translateNameDict forKey:[self calculateClassName]];
}

+ (void)hydrateModelProperties:(Class)class translateDictionary:(NSMutableDictionary *)translateDictionary {
    if (!class || class == [NSObject class]){
        return;
    }

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(class, &outCount);
    for (i = 0; i < outCount; i++){
        objc_property_t p = properties[i];
        const char *name = property_getName(p);
        NSString *nsName = [[NSString alloc] initWithCString:name encoding:NSUTF8StringEncoding];
        NSString *lowerCaseName = [nsName lowercaseString];
        [translateDictionary setObject:nsName forKey:lowerCaseName];
        //注意此处哦
        NSString *propertyType = [self getPropertyType:p];
        [self addValidatorForProperty:nsName type:propertyType];
    }
    free(properties);

    [self hydrateModelProperties:class_getSuperclass(class) translateDictionary:translateDictionary];
}

分享到:
评论

相关推荐

    iOS KVC实例

    KVC在许多苹果框架如Core Data、NSKeyValueObserving等中都得到了广泛应用,对于理解和掌握iOS开发具有重要意义。 ### KVC基本概念 1. **键(Key)**:在KVC中,键通常是一个NSString对象,表示你要访问的属性的...

    KVC技术指南 ---ios官方

    **KVC(Key-Value Coding)**是一种在iOS及OS X开发中广泛使用的模式,它允许开发者通过键(Key)来读取或修改对象的属性值,而无需直接调用特定的方法。这种间接访问属性的方式简化了代码编写,并使得属性的访问...

    iOS中KVC-KVO例子

    在iOS开发中,Key-Value Coding (KVC) 和 Key-Value Observing (KVO) 是两种非常重要的机制,它们都是Objective-C中的特性,用于对象属性的动态访问和观察。KVC提供了一种间接访问对象属性的方式,而KVO则允许我们...

    KVC && Runtime

    注意,`_placeholderLabel`是`UITextField`的私有属性,直接访问可能违反苹果的App Store审核规则,因此在实际开发中应避免此类做法,除非充分了解其潜在风险。 结合KVC和Runtime,可以实现更高级的功能,比如动态...

    关于iOS获取属性你真的了解吗?

    总之,iOS中获取属性涉及了Objective-C的特性,如属性、KVC以及Runtime API,理解这些知识点有助于深入掌握iOS开发。熟悉指针、内存管理和Runtime API不仅可以帮助我们更好地调试代码,还能让我们编写出更高效、更...

    iOS 开发面试问题.zip

    - 你能举一个适配器(Adapter)模式在iOS开发中的例子吗? - 什么是代理(Delegate)模式,以及它在处理事件和通信中的作用? **3. 数据管理** - CoreData和SQLite的区别是什么?在什么情况下选择CoreData? - 如何...

    iOS开发人员必看资料(共100个)

    在iOS开发领域,掌握必要的知识和技能是至关重要的。这份"iOS开发人员必看资料(共100个)"的资源集合,显然是一个全面的学习宝库,旨在帮助开发者提升专业技能,理解并掌握iPhone应用开发的核心技术。下面将详细...

    iOS自定义KVC的实现和使用.zip

    了解并掌握KVC的实现和使用,能够使我们在开发iOS应用时更加灵活,特别是在处理动态数据和对象交互时。KVC提供了一种强大且灵活的方式来访问和操作对象的属性,是Objective-C和Swift开发者的重要工具。通过自定义KVC...

    KVO-KVC-demo

    通过分析提供的代码,我们可以学习到如何在实践中应用这些概念,了解KVC和KVO的正确使用方式和潜在的陷阱。 在实际项目中,KVC和KVO结合使用可以创建出强大的数据驱动的应用。例如,模型对象可以通过KVC轻松地序列...

    IOS 页面之间几种传值方式(单例,代理,kvc)

    在iOS开发中,页面间的通信和数据传递是十分常见的需求。本教程将详细介绍三种主要的传值方式:单例(Singleton)、代理(Delegate)以及Key-Value Coding(KVC)。理解并熟练掌握这些方法,能有效提升应用的交互性...

    iOS开发高级知识.zip

    在iOS开发领域,掌握高级知识是提升应用质量与性能的关键。这个名为"IOS开发高级知识.zip"的压缩包文件很可能是包含一系列关于iOS高级开发技术的示例代码、教程或者项目案例,其名称"IOS-senior-learning-example-...

    IOS新手入门学习资料

    在进入iOS开发的世界之前,首先我们要理解...通过深入学习并实践这些内容,你将逐步掌握iOS开发技能,踏上成为一名合格的iOS开发者之路。记得实践是检验真理的唯一标准,多动手编程,不断尝试,你将在实践中不断成长。

    iOS Apprentice Updated for Swift 4.2 & iOS 12

    《iOS Apprentice Updated for Swift 4.2 & iOS 12》是2018年发布的一份全面且更新至最新技术的iOS开发教程,旨在...通过实践项目,你可以逐步掌握iOS开发的基本流程和技巧,为成为一名合格的iOS开发者打下坚实的基础。

    iOS开发杂货铺 面试题+考试试卷+懒人开发tips.zip

    在iOS开发领域,开发者需要掌握一系列的技术和概念,才能创建出功能强大、用户体验优秀的应用程序。"iOS开发杂货铺 面试题+考试试卷+懒人开发tips.zip"这个压缩包文件显然为学习和进阶iOS开发提供了一套丰富的资源。...

    ios 面试题目及答案

    标题 "iOS 面试题目及答案" 指出了文件内容主要围绕iOS开发相关的面试题目和答案展开,覆盖了iOS开发中的一些核心概念和技术点。描述部分说明这些面试题目非常全面,涉及了Objective-C、Cocoa Touch以及Xcode的使用...

    iOS高级经典面试(2019).pdf.zip

    总之,这份压缩包中的知识点全面覆盖了iOS开发的多个重要方面,无论是面试还是日常开发,对这些概念和技术的掌握都将极大地提升你的iOS开发能力。学习并熟练运用这些知识,将助你在iOS开发的道路上更进一步。

    iOS开发面试题

    2. **MVC模式**:作为iOS开发的基础设计模式,面试官可能会让你解释Model-View-Controller的概念,以及它如何在应用中工作,如何处理数据流和事件响应。 3. **Auto Layout与Size Classes**:理解如何使用Auto ...

    iOS面试知识宝典无水印版.pdf(含oc和swift知识)

    iOS面试知识宝典无水印版.pdf是一本专注于iOS开发相关面试知识点的书籍,覆盖了Objective-C和Swift两种主流的iOS开发语言。这本书适合准备参加iOS开发职位面试的求职者,尤其是那些希望能够全面复习基础知识的应聘者...

    ios开发大全

    《iOS开发大全》 在iOS开发领域,开发者需要掌握一系列的关键技术来构建高效、美观的应用程序。本资源包聚焦于iOS开发中的核心概念,包括UITableView的使用、XML通信与解析等重要主题。以下是对这些知识点的详细...

    ios应用源码之类似js的checkbox效果的效果库 2018128

    这两种语言都是iOS开发的常用语言,Swift更现代,Objective-C则历史悠久。 6. **协议与代理**:为了将checkbox的状态传递到其他组件,库可能采用了协议(Protocol)和代理(Delegate)设计模式,允许接收方在...

Global site tag (gtag.js) - Google Analytics