浅谈KAC

今天我研究了一下KVC,下面我将浅谈一下我对KVC的认识,可能认识不足,我会在后续学习生活中改正.

首先,看到KVC,我们会想这个知识点是干嘛的,其实我们了解一下,就会发现KVC(Key-Value-Coding),键值编码

KVC主要是用来间接访问实例变量(赋值)...

下面我们看一下苹果给的KVC的官方文档:

/* Given a value and a key that identifies an attribute, set the value of the attribute. Given an object and a key that identifies a to-one relationship, relate the object to the receiver, unrelating the previously related object if there was
one. Given a collection object and a key that identifies a to-many relationship, relate the objects contained in the collection to the receiver, unrelating previously related objects if there were any.

The default implementation of this method does the following:

1. Searches the class of the receiver for an accessor method whose name matches the pattern -set<Key>:. If such a method is found the type of its parameter is checked. If the parameter type is not an object pointer type but the value is nil
-setNilValueForKey: is invoked. The default implementation of -setNilValueForKey: raises an NSInvalidArgumentException, but you can override it in your application. Otherwise, if the type of the method‘s parameter is an object pointer type the method is simply
invoked with the value as the argument. If the type of the method‘s parameter is some other type the inverse of the NSNumber/NSValue conversion done by -valueForKey: is performed before the method is invoked.

2. Otherwise (no accessor method is found), if the receiver‘s class‘ +accessInstanceVariablesDirectly method returns YES, searches the class of the receiver for an instance variable whose name matches the pattern _<key>, _is<Key>, <key>, or
is<Key>, in that order. If such an instance variable is found and its type is an object pointer type the value is retained and the result is set in the instance variable, after the instance variable‘s old value is first released. If the instance variable‘s
type is some other type its value is set after the same sort of conversion from NSNumber or NSValue as in step 1.

3. Otherwise (no accessor method or instance variable is found), invokes -setValue:forUndefinedKey:. The default implementation of -setValue:forUndefinedKey: raises an NSUndefinedKeyException, but you can override it in your application.

上面主要说的是

间接为变量赋值,当调用

setValue:  forKey:

或者

setValue: forKeyPath:

key用来标识实例变量

value实例变量对应的值

优先找_<key>, _is<Key>, <key>, or is<Key>,这个格式的实例变量,如果有的话,就直接赋值,如果没有就会产生异常

主要由两种异常,上面苹果文档也给出了解决方法.

第一:当key为非对象类型,且Value设置为nil的时候,会调用这个方法,系统是默认实现是抛出一个异常,我们可以重写这个方法,解决Value为nil的问题

- (void)setNilValueForKey:(NSString *)key;

- (void)setNilValueForKey:(NSString *)key

{

}

第二,当key不存在的时候,会调用这个方法,系统的默认实现是抛出一个异常,我们可以重写这个方法,解决key不存在的问题

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

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

{

}

然后在说说

setValue:  forKey:

或者

setValue: forKeyPath:

还有

setValuesForKeysWithDictionary:

这三个方法的区别,

setValue:  forKey:  主要是间接为一个类中的单个实例变量赋值,如

[p setValue:@"张三"
forKey:@"_name"];

setValue: forKeyPath:主要是间接的为一个类中,单个实例变量,这个实例变量也是一个类,然后这个类的实例变量赋值,下面的点      表示一个类中,实例变量,这个实例变量也是一个类,然后这个类的实例变量

[p setValue:@"哇哈哈"
forKeyPath:@"a.name"];

setValuesForKeysWithDictionary:  主要是间接的为一个类中的所有实例变量赋值

[p setValuesForKeysWithDictionary:@{@"name":
@"张三",@"age":@19,@"sex":@"男"}];

好了,今天就这些,如果上面看不懂,可以跟下面的代码一块看....

#import <Foundation/Foundation.h>
#import "A.h"
@interface Person : NSObject
{
    NSString * _name;
    NSInteger _age;
    A * _a;
}

- (instancetype)init;
- (void)saiHi;

- (void)setNilValueForKey:(NSString *)key;
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
#import "Person.h"

@implementation Person
- (void)saiHi
{
    NSLog(@"hello this is %@ %ld years old      ",_name,_age);
    [_a printName];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _a = [[A alloc]init];
    }
    return self;
}
//当key为非对象类型,且value设置为nil的时候,会调用这个方法,系统的默认实现是抛出一个异常,我们可以重写这个方法,解决value为nil的问题
- (void)setNilValueForKey:(NSString *)key
{

}
//当key不存在的时候,会调用这个方法,系统的默认实现是抛出一个异常,我们可以重写这个方法,解决key不存在的问题
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{

}

@end
#import <Foundation/Foundation.h>

@interface A : NSObject
{
    NSString * _name;

}

- (void)printName;
@end
#import "A.h"

@implementation A
- (void)printName
{
    NSLog(@"%@",_name);
}
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{

    //KVC 苹果脚本语言, 间接为变量赋值
    Person * p = [[Person alloc]init];
    [p setValue:@"张三" forKey:@"_name"];
//    [p valueForKey:@"账上"];
    [p setValue:@34 forKey:@"age"];

    [p setValue:@"男" forKey:@"sex"];
    //1.优先找setSex
    //2._sex
    //3._isSex
    //4.sex
    //5.isSex
    //如果没有,空,没有产生异常
    //可以重写解决异常

    //后期可以定义空类,加属性,定义一个万能的类

    //上面可以都不写

    [p setValuesForKeysWithDictionary:@{@"name": @"张三",@"age":@19,@"sex":@"男"}];

//    [p setValue:[a set] forKey:@"A"]
    //setValue: forKeyPath    可以给变量的变量的变量赋值
    [p setValue:@"哇哈哈" forKeyPath:@"a.name"];
    //当没有a的空间时,也没法给a赋值,
    //当把a开辟了空间,通过keyPath就可以赋值了
    [p saiHi];

    //处理空就写setNilValue方法就行了
    return 0;
}

发给客户

浅谈KAC,布布扣,bubuko.com

时间: 2024-12-21 13:28:57

浅谈KAC的相关文章

.net中对象序列化技术浅谈

.net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数 据.例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象.反之,反序列化根据流重新构造对象.此外还可以将对象序列化后保存到本地,再次运行的时候可以从本地文件 中“恢复”对象到序列化之前的状态.在.net中有提供了几种序列化的方式:二进制序列化

浅谈——页面静态化

现在互联网发展越来越迅速,对网站的性能要求越来越高,也就是如何应对高并发量.像12306需要应付上亿人同时来抢票,淘宝双十一--所以,如何提高网站的性能,是做网站都需要考虑的. 首先网站性能优化的方面有很多:1,使用缓存,最传统的一级二级缓存:2,将服务和数据库分开,使用不同的服务器,分工更加明确,效率更加高:3,分布式,提供多台服务器,利用反向代理服务器nginx进行反向代理,将请求分散开来:4,数据库的读写分离,不同的数据库,将读操作和写操作分开,并实时同步即可:5,分布式缓存,使用memc

单页应用SEO浅谈

单页应用SEO浅谈 前言 单页应用(Single Page Application)越来越受web开发者欢迎,单页应用的体验可以模拟原生应用,一次开发,多端兼容.单页应用并不是一个全新发明的技术,而是随着互联网的发展,满足用户体验的一种综合技术. SEO 一直以来,搜索引擎优化(SEO)是开发者容易忽略的部分.SEO是针对搜索(Google.百度.雅虎搜索等)在技术细节上的优化,例如语义.搜索关键词与内容相关性.收录量.搜索排名等.SEO也是同行.市场竞争常用的的营销手段.Google.百度的搜

浅谈html标签

浅谈html各常用标签用法 标题标签:<h1>-<h6>来表示,使标题字体变粗. <br />换行标记 <hr />水平分隔符 &nbsp空格符 &copy版权符 <a href>a标签超链接 href可接链接地址 <p>段落标签<blockquote>引用标签及可用做缩进 <table>表格中的<ul>无序列表<ol>有序列表<dl>自定义列表<row

浅谈二维中的树状数组与线段树

一般来说,树状数组可以实现的东西线段树均可胜任,实际应用中也是如此.但是在二维中,线段树的操作变得太过复杂,更新子矩阵时第一维的lazy标记更是麻烦到不行. 但是树状数组在某些询问中又无法胜任,如最值等不符合区间减法的询问.此时就需要根据线段树与树状数组的优缺点来选择了. 做一下基本操作的对比,如下图. 因为线段树为自上向下更新,从而可以使用lazy标记使得矩阵的更新变的高校起来,几个不足就是代码长,代码长和代码长. 对于将将矩阵内元素变为某个值,因为树状数组自下向上更新,且要满足区间加法等限制

[nRF51822] 14、浅谈蓝牙低功耗(BLE)的几种常见的应用场景及架构(科普类干货)

蓝牙在短距离无线通信领域占据举足轻重的地位—— 从手机.平板.PC到车载设备, 到耳机.游戏手柄.音响.电视, 再到手环.电子秤.智能医疗器械(血糖仪.数字血压计.血气计.数字脉搏/心率监视器.数字体温计.耳温枪.皮肤水分计等), 再到智能家居等领域均占有一席之地. 而蓝牙低功耗(BLE)是在蓝牙4.0协议上修改以适用低功耗应用场景的一种蓝牙协议. 随着上一股智能消费类电子大潮的到来,BLE的各种应用也像雨后春笋般在市场上铺开. 如果想 紧跟蓝牙协议的最新动态 ,可以在https://www.b

浅谈C++容器动态内存管理的优化

在信息学竞赛中,C++的容器的用途非常广泛,但经常因常数过大而超时.怎样才能提高它们的效率呢? 我们知道,容器是存储同一类对象的对象,既然"对象"我们无法改变,那么我们只能从"存储"入手,不难想到,不同容器在实现上的根本区别是它们对应着不同的内存组织方式,内存管理无疑是这种实现的核心,所以优化内存管理是加快容器效率的最好途径之一. 一.内存分配器简介 怎样才能优化内存管理呢?很简单,C++为我们提供了这样的接口,我们可以通过自定义容器模板中的最后一个allocato

张小龙浅谈微信公众平台的意义

腾讯高级副总裁张小龙表示:微信公众平台,就是在移动互联网时代,让企业和个人以更简捷的形式提供服务给有需要的人. 张小龙浅谈微信公众平台的意义,布布扣,bubuko.com

浅谈数据库系统中的cache(转)

http://www.cnblogs.com/benshan/archive/2013/05/26/3099719.html 浅谈数据库系统中的cache(转) Cache和Buffer是两个不同的概念,简单的说,Cache是加速"读",而buffer是缓冲"写",前者解决读的问题,保存从磁盘上读出 的数据,后者是解决写的问题,保存即将要写入到磁盘上的数据.在很多情况下,这两个名词并没有严格区分,常常把读写混合类型称为buffer cache,本文后续的论述中,统一