iOS开发——高级技术OC篇&运行时(Runtime)机制
运行时(Runtime)机制
官方介绍:


这里我们主要关注的是最后一种!
下面来看看Runtime的相关总结

#pragma mark 获取属性成员
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 unsigned int count = 0;
2
3 Ivar *ivars = class_copyIvarList([iCocosObject class], &count);
4
5 // Ivar *ivars = class_copyMethodList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
6
7 // Ivar *ivars = class_copyPropertyList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>);
8
9 // Ivar *ivars = class_copyProtocolList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
10
11
12
13 for (int i = 0; i < count; i++) {
14
15 Ivar ivar = ivars[i];
16
17
18
19 NSString *name = @(ivar_getName(ivar));
20
21 NSLog(@"%@", name);
22
23
24
25 NSLog(@"*****************");
26
27 const char *iv = ivar_getName(ivar);
28
29
30
31
32
33 NSLog(@"%s", iv);
34
35
36
37 NSLog(@"*****************");
38
39 const char *ivs = ivar_getTypeEncoding(ivar);
40
41
42
43 NSLog(@"%s", ivs);
44
45 }

#pragma mark 获取方法
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 unsigned int meth = 0;
2
3 Method *met = class_copyMethodList([iCocosObject class], &meth);
4
5 for (int i = 0; i < meth; i++) {
6
7 Method m = met[i];
8
9
10
11 SEL sel = method_getName(m);
12
13 NSString *str = NSStringFromSelector(sel);
14
15
16
17 NSLog(@"%@",str);
18
19 }
20
21

#pragma mark 获取协议
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 unsigned int pro = 0;
2
3 Protocol * __unsafe_unretained *proto = class_copyProtocolList([iCocosObject class], &pro);
4
5 for (int i = 0; i < pro; i++) {
6
7 Method p = (__bridge Method)(proto[i]);
8
9
10
11 const char *pr = protocol_getName((__bridge Protocol *)(p));
12
13 // NSString *str = NSStringFromSelector(pr);
14
15
16
17 NSLog(@"%s",pr);
18
19 }
20
21

#pragma mark 获取属性
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 unsigned int xs = 0;
2
3 objc_property_t *xsL = class_copyPropertyList([iCocosObject class], &xs);
4
5 for (int i = 0; i < xs; i++) {
6
7 objc_property_t xslist = xsL[i];
8
9
10
11 const char *x = property_getName(xslist);
12
13 // NSString *str = NSStringFromSelector(x);
14
15
16
17 NSLog(@"%s",x);
18
19 }
20
21
22
23
24
25 // objc_msgSend()
26
27 // objc_getClass(<#const char *name#>);
28
29 // sel_registerName(<#const char *str#>);
30
31
32
33 // iCocosView *view = objc_msgSend(objc_msgSend(objc_getClass("iCocosView"), sel_registerName("alloc")), sel_registerName("init"));
34
35
36
37

#pragma mark 实现方法混淆
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 Method one = class_getClassMethod([iCocosObject class], @selector(iCocosMethos)); 2 3 Method two = class_getClassMethod([iCocosObject class], @selector(iCocosMetho)); 4 5 method_exchangeImplementations(one, two); 6 7 8 9 Method o = class_getInstanceMethod([iCocosObject class], @selector(iCocosMethos)); 10 11 Method t = class_getInstanceMethod([iCocosObject class], @selector(iCocosMetho)); 12 13 method_exchangeImplementations(o, t); 14 15 16 17 // class_getInstanceSize(<#__unsafe_unretained Class cls#>); 18 19 // class_getInstanceVariable(<#__unsafe_unretained Class cls#>, <#const char *name#>); 20 21 // class_getMethodImplementation_stret(<#__unsafe_unretained Class cls#>, <#SEL name#>); 22 23 24 25 // class_getClassVariable(<#__unsafe_unretained Class cls#>, <#const char *name#>); 26 27 // class_getSuperclass(<#__unsafe_unretained Class cls#>); 28 29 30 31 // class_getProperty(<#__unsafe_unretained Class cls#>, <#const char *name#>); 32 33 // class_getName(<#__unsafe_unretained Class cls#>); 34 35 36 37 38 39 40 41 // class_replaceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>, <#IMP imp#>, <#const char *types#>); 42 43

#pragma mark 增加
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 // class_addIvar(<#__unsafe_unretained Class cls#>, <#const char *name#>, <#size_t size#>, <#uint8_t alignment#>, <#const char *types#>); 2 3 // class_addMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>, <#IMP imp#>, <#const char *types#>); 4 5 // class_addProperty(<#__unsafe_unretained Class cls#>, <#const char *name#>, <#const objc_property_attribute_t *attributes#>, <#unsigned int attributeCount#>); 6 7 // class_addProtocol(<#__unsafe_unretained Class cls#>, <#Protocol *protocol#>); 8 9

#pragma mark 替换系统的addObject:(给数组或者其他类型做分类)
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

1 //在load中实现下面的代码
2
3 Method ic = class_getInstanceMethod(NSClassFromString(@"_NSArrayM"), @selector(iCocosobject:));
4
5 Method add = class_getInstanceMethod(NSClassFromString(@"_NSArrayM"), @selector(addObject:));
6
7 method_exchangeImplementations(ic, add);
8
9
10
11
12
13 //实现iCocosobject方法:(实现相应的功能,这里只是去掉非空)
14
15 // if (object != nil) {
16
17 // [self iCocosobject:object];
18
19 // }
20
21



#pragma mark 消息机制
/******************************************************************************
* *
* Inquiry macros *
* *
* iCocos--Description *
* *
******************************************************************************/

objc_msgSend(); // objc_getClass(<#const char *name#>); // objc_getMetaClass(<#const char *name#>); // objc_getClassList(<#__unsafe_unretained Class *buffer#>, <#int bufferCount#>); // objc_getProtocol(<#const char *name#>); // object_getIvar(<#id obj#>, <#Ivar ivar#>); // objc_getRequiredClass(<#const char *name#>); // objc_getAssociatedObject(<#id object#>, <#const void *key#>);//关联对象 } @end

来看看我们平时使用OC编写的代码转成C++之后是什么样的

创建一个分类实现任何对象都可以使用方法混淆

1
2
3 @implementation NSObject(Extension)
4
5
6
7 /**
8
9 * 给NSObject添加一个分类
10
11 */
12
13
14
15 +(void)swizzleClassMethod:(Class)class originalSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
16
17 {
18
19 Method other = class_getClassMethod(class, otherSelector);
20
21 Method origin = class_getClassMethod(class, originSelector);
22
23 method_exchangeImplementations(other, origin);
24
25 }
26
27
28
29 +(void)swizzleInstanceMethod:(Class)class originalSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
30
31 {
32
33 Method other = class_getInstanceMethod(class, otherSelector);
34
35 Method origin = class_getInstanceMethod(class, originSelector);
36
37 method_exchangeImplementations(other, origin);
38
39 }
40
41 @end


应用实例--------------------------------------------------
一:关联对象:给某一个类在运行的时候动态的增加一个成员变量

1 @interface NSObject(iCocos)
2
3
4
5 //头文件中声明一个属性
6
7 @property (nonatomic, assign) double height;
8
9
10
11 @end
12
13
14
15
16
17 @implementation NSObject(iCocos)
18
19
20
21 static double heightKey;//用来参考
22
23
24
25 -(void)setHeight:(double)height
26
27 {
28
29 objc_setAssociatedObject(self, &heightKey, @(height), OBJC_ASSOCIATION_ASSIGN);
30
31 }
32
33
34
35 -(double)height
36
37 {
38
39 return [objc_getAssociatedObject(self, &heightKey) doubleValue];
40
41 }
42
43
44
45 @end
46
47

二:归档

三:字典转模型:
之前使用的方法;

使用运行时
注意必须保证字典中的属性名和模型中的属性名一模一样

完善代码:

1 @implementation NSObject (Model)
2
3
4
5 + (instancetype)objcWithDict:(NSDictionary *)dict mapDict:(NSDictionary *)mapDict
6
7 {
8
9
10
11
12
13 id objc = [[self alloc] init];
14
15
16
17 unsigned int count = 0;
18
19 Ivar *ivars = class_copyIvarList(self, &count);
20
21
22
23 for (int i = 0; i < count; i++) {
24
25 Ivar ivar = ivars[i];
26
27
28
29 NSString *name = @(ivar_getName(ivar));
30
31
32
33 name = [name substringFromIndex:1];
34
35
36
37 id value = dict[name];
38
39
40
41 if (value == nil) {
42
43
44
45 if (mapDict) {
46
47 NSString *mapName = mapDict[name];
48
49
50
51 value = dict[mapName];
52
53 }
54
55
56
57 }
58
59
60
61 [objc setValue:value forKeyPath:name];
62
63 }
64
65
66
67
68
69 return objc;
70
71 }
72
73
74
75 @end

四:封装框架:MJExtension
iOS开发——高级技术OC篇&运行时(Runtime)机制的更多相关文章
- iOS开发——高级UI—OC篇&退出键盘
退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中 ...
- iOS开发——使用技术OC篇&简单九宫格锁屏功能的实现与封装
简单九宫格锁屏功能的实现与封装 首先来看看最后的实现界面. 在这开始看下面的内容之前希望你能先大概思考活着回顾一下如果 你会怎么做,只要知道大概的思路就可以. 由于iphone5指纹解锁的实现是的这个 ...
- iOS开发——高级技术精选OC篇&Runtime之字典转模型实战
Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...
- iOS开发——运行时OC篇&使用运行时获取系统的属性:使用自己的手势修改系统自带的手势
使用运行时获取系统的属性:使用自己的手势修改系统自带的手势 有的时候我需要实现一个功能,但是没有想到很好的方法或者想到了方法只是那个方法实现起来太麻烦,一或者确实为了装逼,我们就会想到iOS开发中最牛 ...
- iOS开发——底层OC篇&运行时常用
运行时常用 什么是Runtime(前面的文章已经说的很清楚了,这里就简单的介绍一下) 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如[target doSomething]; ...
- ios开发——实用技术篇OC篇&iOS的主要框架
iOS的主要框架 阅读目录 Foundation框架为所有的应用程序提供基本系统服务 UIKit框架提供创建基于触摸用户界面的类 Core Data框架管着理应用程序数据模型 Core ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据
网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据
网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...
- iOS开发——新特性OC篇&IOS9 SDK新特性
iOS9 SDK新特性 WWDC 2015苹果开发者大会是移动开发者一年一度的盛会,InfoQ中文站除了第一时间整理Keynote内容分享给大家之外,还邀请了资深的一线开发者分享他们的收获.本文为王巍 ...
随机推荐
- 禁止Visual Studio中的编译警告
VC编译器有个很蛋痛的自家警告系统,默认下各种开源库比如CGAL,各种4996,而一般自己写的 如sscanf,fopen这种单个文件,在文件头加个 #pragma warning (disable ...
- First Missing Positive && missing number
https://leetcode.com/problems/first-missing-positive/ 我原以为数组中不会有重复的数字,所以利用min.max分别记录给定数组中出现的最小正整数和最 ...
- ruby 学习笔记 2 -变量
变量 在ruby的世界里,变量有5种,全局变量 局部变量 实例变量 常量 类变量以及伪变量 常用的: 全局: 在全局使用,使用$开头,因为是全局的,所以在任何的代码例子中都可以改变其值,造成混乱,所以 ...
- JAVA里面的IO流(一)分类2(节点流和处理流及构造方法概要)
IO流根据处理对象的不同分为节点流和处理流. 直接对文件进行处理的流为节点流: 对流进行包装从而实现对文件的优化处理的流为处理流. 节点流类型: 可以看出,节点流主要分这几大类: 文件流 文件流构造方 ...
- VMware Workstation虚拟机中的Linux通过NAT模式共享上网配置教程
VMware Workstation虚拟机中的Linux通过NAT模式共享上网配置教程 在VMware Workstation虚拟机下面,Linux虚机要上网,一般是桥接模式,但我自己的电脑上网的环境 ...
- Windows & Office完美结合,助力办公
虚拟桌面——休闲工作分开来 Windows 10最令我欣愉的是加入了虚拟桌面的功能. 作为一名拖延症晚期患者,早已病入膏肓.每次工作时总会不知不觉地将实现转移到已经打开的浏览器及聊天工具上,时间就这样 ...
- RHEL6.5及Win7的和谐共处(投机版)
背景: 在Windows XP存在时,装了个RHEL6.5,用的是安装程序自带的Grub,后来将XP删除后重装了Windows7,RHEL的Grub被覆盖,启动不了RHEL了,于是补上RHEL的引导… ...
- 百度ueditor 实例化 Cannot set property 'innerHTML' of null 完美解决方案
此时此刻,我正在用博客园推荐的TinyMCE编辑器写这个博客,突然想起最近在项目中使用百度ueditor编辑器中的一些经历.所以记录在此,与大家分享. 不得不说,百度ueditor是一款很好的在线编辑 ...
- arm v5,v6,v7?
http://blog.csdn.net/woshi_ziyu/article/details/7946862
- 在CentOS上搭建svn服务器及注意事项
系统环境 CentOS 5.9 推荐使用yum install安装,比较简单 一.检查是否已经安装其他版本svn # rpm -qa subversion #卸载svn # yum remove ...