重写KVC
#import "NSObject+WQKVC.h"
#import <objc/runtime.h>
/**
KVC
首先调用的方法顺序:
|- setter: setKey -> setIsKey
|- getter: getKey -> key -> isKey
|- - (Bool)accessInstanceVariablesDirectly 不为NO ,默认为YES
查找成员变量的顺序:
|- _key -> _isKey -> key -> isKey
**/ @implementation NSObject (WQKVC)
- (void)WQ_setValue:(id)value forKey:(NSString *)key
{
//判断key的合法性
if (key.length == || key == nil) {
return;
}
NSString *setKey = [NSString stringWithFormat:@"set%@",key.capitalizedString];
SEL setKeyMethod = NSSelectorFromString(setKey);
if ([self respondsToSelector:setKeyMethod]) {
[self performSelector:setKeyMethod withObject:value];
return;
} NSString *setIsKey = [NSString stringWithFormat:@"setIs%@",key.capitalizedString];
SEL setIsKeyMethod = NSSelectorFromString(setIsKey);
if ([self respondsToSelector:setIsKeyMethod]) {
[self performSelector:setIsKeyMethod withObject:value];
return;
} if (![self.class accessInstanceVariablesDirectly]) {
NSException *exception = [NSException exceptionWithName:@"WQKVC Exception" reason:@"不能设置为NO!" userInfo:nil];
@throw exception;
return;
} unsigned int count = ;
Ivar *ivasList = class_copyIvarList([self class], &count);
// _Key
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
} // _isKey
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_is%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
} // Key
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:key]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
} // isKey
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"is%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
} // 异常处理!
[self setValue:value forUndefinedKey:key];
free(ivasList);
} - (id)WQ_valueForKey:(NSString *)key
{
if (key.length == || key == nil) {
return nil;
} // getKey -- Method
NSString *getKey = [NSString stringWithFormat:@"get%@",key.capitalizedString];
SEL getKeyMethod = NSSelectorFromString(getKey);
if ([self respondsToSelector:getKeyMethod]) {
return [self performSelector:getKeyMethod withObject:nil];
} // key -- Method
SEL KeyMethod = NSSelectorFromString(key);
if ([self respondsToSelector:getKeyMethod]) {
return [self performSelector:KeyMethod withObject:nil];
} // isKey -- Method
NSString *isKey = [NSString stringWithFormat:@"is%@",key.capitalizedString];
SEL isKeyMethod = NSSelectorFromString(isKey);
if ([self respondsToSelector:isKeyMethod]) {
return [self performSelector:isKeyMethod withObject:nil];
} if (![self.class accessInstanceVariablesDirectly]) {
NSException *exception = [NSException exceptionWithName:@"WQKVC Exception" reason:@"不能设置为NO!" userInfo:nil];
@throw exception;
return nil;
} unsigned int count = ;
Ivar *ivasList = class_copyIvarList([self class], &count);
// _Key
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
} // _isKey
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_is%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
} // Key
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:key]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
} // isKey
for (int i = ; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"is%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
} free(ivasList);
return [self valueForUndefinedKey:key]; } @end
重写KVC的更多相关文章
- KVO VS isa : KVO 建立在 KVC 之上
Key-Value Observing (KVO) 建立在 KVC 之上,它通过重写 KVC 和监听 setter 方法,向外发送通知. https://blog.csdn.net/y55091811 ...
- iOS Runtime原理及使用
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- (转)iOS-Runtime知识点整理
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- iOS - 回顾总结Runtime原理及使用
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- Objective-C之KVC、KVO
1,KVC(键值编码) Key Value Coding 1.1在C#中,可以通过字符串反射来获取对象,从而对对象的属性进行读写,Object-C中有同样的实现,通过字符串(属性名词)对对象的属性进 ...
- KVC 和 KVO
KVC 键值编码 全称是Key-value coding,翻译成键值编码.它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制. 1.通过key(成员变量的名称)设置 ...
- 11. KVC And KVO
1. KVC And KVO 的认识 KVC/KVO是观察者模式的一种实现 KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...
- iOS开发系列--Objective-C之KVC、KVO
概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...
- KVC & KVO
KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思.KVO是Key-Value Observing的简写,是键值观察的意思.那么我们能拿KV ...
随机推荐
- 技巧:开启ubuntu系统桌面上的右键进入terminal命令行控制台功能
$ sudo apt-get install nautilus-open-terminal 执行上述命令,重启. 重启命令: $ sudo reboot 注意:需要联网
- Vue 中怎么发起请求(一)
1.vue 支持开发者引入 jquery 使用 $.ajax() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1.首先,在 package.json 中添加 j ...
- 手工安装XDB 组件in oracle 11g
#############. sample 1 install guide below step is only for oracle 11g database installation, 10g d ...
- python_文件 处理
一.字符编码 内存固定使用unicode编码 数据最先产生于内存中,是unicode格式,要想传输需要转成bytes格式 # unicode -------> enconde( u t f - ...
- oracle impdp时卡死Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
今天在用impdp导入时,Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX卡在建索引的过程一直不动,也不报错,重试了好几遍还是这样. 后来恍 ...
- checkbox多选、全选js效果
//全选checkbox function allCheck() { //全选input var all = $("input[name='all']"); //全部的input ...
- [转]分享20佳好玩的 jQuery 游戏
本文转自:http://www.cnblogs.com/lhb25/archive/2011/04/17/2001089.html jQuery是时下最流行的 JavaScript 库.现在,除了HT ...
- [转]怎么样快速入门AngularJS?
本文转自:http://www.ngnice.com/posts/205af1ea1e13d2 怎么样快速学习AngularJS? 相信很多初学者都有过或者类似的疑问,其实这个问题没有标准的答案,每个 ...
- SpringMVC restful风格
1.Spring对REST的支持 Spring3(这里讨论Spring3.2+)对Spring MVC的一些增强功能为REST提供了良好的支持.Spring对开发REST资源提供以下支持: 操作方式: ...
- C语言实现通用链表初步(一)
注意:本文讨论的是无头单向非循环链表. 假设不采用Linux内核链表的思路,怎样用C语言实现通用链表呢? 一种常用的做法是: typedef int element_t; struct node_in ...