iOS开发——高级技术OC篇&运行时(Runtime)机制

运行时(Runtime)机制

本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档。

下面就来看看什么是运行时,我们要怎么在iOS开发中去使用它。

官方介绍:

这里我们主要关注的是最后一种!

下面来看看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

时间: 2024-10-12 08:45:11

iOS开发——高级技术OC篇&运行时(Runtime)机制的相关文章

iOS开发——高级UI—OC篇&amp;退出键盘

退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中的一种活着几种. 一:textView 1 //通过委托来实现放弃第一响应者 2 #pragma mark - UITextView Delegate Method 3 -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(N

iOS开发——使用技术OC篇&amp;项目实战总结之开发技巧

项目实战总结之开发技巧 本文收集了25个关于可以提升程序性能的提示和技巧 1.使用ARC进行内存管理 2.在适当的情况下使用reuseIdentifier 3.尽可能将View设置为不透明(Opaque) 4.避免臃肿的XIBs 5.不要阻塞主线程 6.让图片的大小跟UIImageView一样 7.选择正确的集合 8.使用GZIP压缩 9.重用和延迟加载View 10.缓存.缓存.缓存 11.考虑绘制 12.处理内存警告 13.重用花销很大的对象 14.使用Sprite Sheets 15.避免

iOS开发——使用技术OC篇&amp;保存(获取)图片到(自定义)相册

保存(获取)图片到(自定义)相册 最近在学 iOS相关技术(绘图篇实现画板功能)的时候设计到了两个常用的知识点,那就是保存图片到相册和葱相册中获取图片. 只是个人比较好奇拓展一些技术,说的难听点叫做装牛角尖,好听点就是为了装逼而已,所以在保存相册的时候使用真及测试发现不能保存到我iPhone里 main的自定义相册里面,就查看文档和资料,也借鉴别人的分享实现了想要的功能,就把他给记录下来,这个虽然没有直接保存和获取常用但是也是一项很好的实用技术. 一:首先来看看怎么获取相册的图片: 1 // 弹

iOS开发——使用技术OC篇&amp;剪切版的实现

剪切版的实现 在iOS中,可以使用剪贴板实现应用程序之中以及应用程序之间实现数据的共享.比如你可以从iPhone QQ复制一个url,然后粘贴到safari浏览器中查看这个链接的内容. 一.在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView 二.UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能. 1.UIPasteboard:我们可以向其中写入数据,也可以读取数据 2.UIMe

iOS开发——实战技术OC篇&amp;应用帮助界面简单实现

应用帮助界面简单实现 有的时候我们可能遇到一些关于应用中的技术或者信息不够明确,所以在使用应用的时候可能会遇到一些不知道所措的情况,比如关于一些难一点的游戏应用的操作,关于应用中一些比较隐藏的功能疑惑是操作完成后需要用户去根据需求做其他相应操作的的功能,所以这里我们就实现一个简单的帮组界面,也许跟实际开发中有一些区别,但是思路理解基本上就没有什么问题了. 我们知道平时帮助界面来说,可能是使用一个掩饰案例,可能是网络连接,也能是说明文档,这里我们就简单一点使用网页结合JSON数据来实现,网页实现也

iOS开发——使用技术OC篇&amp;简单九宫格锁屏功能的实现与封装

简单九宫格锁屏功能的实现与封装 首先来看看最后的实现界面. 在这开始看下面的内容之前希望你能先大概思考活着回顾一下如果 你会怎么做,只要知道大概的思路就可以. 由于iphone5指纹解锁的实现是的这个功能呗淘汰,但是你可能会在想,都淘汰了你还在这里说个毛线啊,其实大家都知道,编程注重的思想,当然会了这个你不可能就会了指纹技术,哪还得等笔者在后面的学习中给大家分享,只是或许有一天这种功能或者思路在哪里要用到你不觉得是一件很开心的事情吗,而且如果你是不想自己敲的话直接可以拿来用. 好了不多废话直接上

iOS开发——实战技术OC篇&amp;点击状态栏ScrollView(包括子控件)自动滚到顶部

点击状态栏ScrollView(包括子控件)自动滚到顶部 其实这种方式我们平时见的还是比较多的,而且适合用户的需求,所以就搬来琢磨了一下,感觉效果还不错 这里就直接将解决思路一一写出来不将代码分段展示了,在代码中我加了详细的注释objective-c的套路和swift基本一样,在最后会将Swift和objective-c的代码一起放上,如果需要直接解决问题的童鞋可以直接将代码拷贝到工程里即可 首先创建一个topWindow继承至NSObject,这里我们考虑将这个功能完全封装起来,所以所有的方法

iOS开发——实战技术OC篇&amp;关于蒙板和弹出菜单

关于蒙板和弹出菜单 一:关于蒙板 蒙板的作用一般就是用来实现不能做其他操作还有一些模糊效果提示用户 我们只需要自定义一个View,并且创建两个类方法用来给外界调用实现显示和隐藏 + (void)show; + (void)hide; 显示:直接添加到window上,并且设置和window同样大小,然后设置相应的透明度(alpla) 1 + (void)show 2 3 { 4 5 6 7 8 9 iCocosCover *cover = [[self alloc] init]; 10 11 12

iOS开发——使用技术OC篇&amp;视频和音频简单总结

视频和音频简单总结 1.音效播放(短时间的音频文件) 1> AudioServicesCreateSystemSoundID 2> AudioServicesPlaySystemSound 2.音乐播放(长时间的音频文件)1> AVAudioPlayer 只能播放本地的音频文件 >MPMusicPlayerControllerm 3.视频播放 1> AVPlayer(也可以播放音频) 能播放本地.远程的音频.视频文件 基于Layer显示,得自己去编写控制面板 2> MP