重写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 ...
随机推荐
- 基于Visual Studio .NET2015的单元测试 OpenCover
https://www.cnblogs.com/XiaoRuLiang/p/10095723.html 基于Visual Studio .NET2015的单元测试 1. 在Visual Stud ...
- vim的三种模式
vim的三种模式(最基本的) 命令模式:在该模式下是不能对文件进行编辑的,可以输入快捷键进行一些操作(删除. 复制.移动光标.粘贴)[打开默认 是进入命令模式] 编辑 ...
- c++11 move构造函数和move operator 函数 学习
先看个代码吧!!!!!!!!!! #include <iostream> using namespace std; class A { public: A(){cout<<&q ...
- 未来HTML6出现的10个特性
网络技术正趋向于发展为一个巨大的移动APP市场,在Web开发的革命浪潮中起着指示性作用,自HTML引入以来,创建可转换,有新意的网络移动应用程序变得So easy,web开发中运用先进技术也很容易处理 ...
- IOS Intro - UIWindow UIView and CALayer
UIWindow.UIView以及CALayer之间的关系2016-05-11 20:46 本站整理 浏览(16) UIWindow1.简介UIWindow是一种特殊的UIView,通常在一个app中 ...
- thinkphp3.2 删除Runtime目录里的缓存文件,标记一下,以下好找。
操作如下: utility::clearCache("Data"); 或 utility::clearCache("Data-Logs"); class uti ...
- Murano Weekly Meeting 2016.06.07
Meeting time: 2016.June.7 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: 1.A ...
- (转)AIX 5.3安装SSH .
AIX 5.3安装SSH . 原文:http://blog.csdn.net/chunhua_love/article/details/12004845 环境:OS:AIX 5.3SSH: opens ...
- 硬盘和显卡的访问与控制(二)——《x86汇编语言:从实模式到保护模式》读书笔记02
上一篇博文我们讲了如何看到实验结果,这篇博文我们着重分析源代码. 书中作者为了说明原理,约定了一种比较简单地用户程序头部格式,示意图如下(我参考原书图8-15绘制的,左边的数字表示偏移地址): 所以, ...
- S3C2440 中断相关寄存器小探
========================================== 转载时请注明出处和作者联系方式 文章出处:http://blog.csdn.net/longintchar 作者联 ...