码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-08-16 18:11:58      阅读:3229      评论:0      收藏:0      [点我收藏+]

标签:

运行时(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

 

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

标签:

原文地址:http://www.cnblogs.com/iCocos/p/4734687.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!