iOS中的RunTime机制

/*
OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法。利用runtime机制让我们可以在程序运行时动态修改类、对象中的所有属性、方法,就算是私有方法以及私有属性都是可以动态修改的。本文旨在对runtime的部分特性小试牛刀,更多更全的方法可以参考系统API文件<objc/runtime.h>
1、class_copyPropertyList  获取一份拷贝的成员列表数组
2、property_getName获取成员名称
3、class_getInstanceVariable  获取成员对象的Ivar
4、object_getIvar从Ivar对象中取值
5、object_setIvar赋值函数
*/

#import <Foundation/Foundation.h>

@interface WQClass : NSObject

@property (nonatomic,strong) NSString *age;
- (void)test;

@end


#import "WQClass.h"

@implementation WQClass

- (void)test
{
    NSLog(@"这里是WQClass");
}

@end

#import <Foundation/Foundation.h>

@interface NSObject (RunTimeTest)

- (id)testRunTime:(NSString *)className age:(NSString *)age;

@end

#import "NSObject+RunTimeTest.h"

#import <objc/runtime.h>
#import "WQClass.h"

@implementation NSObject (RunTimeTest)

- (WQClass *)testRunTime:(NSString *)className age:(NSString *)age
{
    //propertyCount 成员属性的数量
    unsigned int propertyCount = 0;
    /* objc_property_t 根据苹果文档的解释:An opaque type that represents an Objective-C declared property.
     个人理解:一个任意类型的对象代表一个oc声明的属性成员 (本人英语水平实在有限)*/
    /* class_copyPropertyList
     文档:Return Value
     An array of pointers of type objc_property_t describing the properties declared by the class. Any properties declared by superclasses are not included. The array contains *outCount pointers followed by a NULL terminator. You must free the array with free().
     个人理解:主要2个意思:返回一个数组指针,类型为objc_property_t,用完要记得free,释放掉。
     */
    objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
    for(unsigned int i=0;i<propertyCount;i++)
    {
        objc_property_t property = properties[i];
        //获取成员的名称
        NSString *propertyName = [[NSString alloc]initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        NSLog(@"-----%@",propertyName);
        
        //获取成员内容
        Ivar ivar = class_getInstanceVariable([self class], [propertyName UTF8String]);
        if(ivar == nil)
        {
            //获取class里面的变量,添加_下划线,就是get方法,然后object_getIvar,就是调用get方法取值
            ivar = class_getInstanceVariable([self class], [[NSStringstringWithFormat:@"_%@",propertyName] UTF8String]);
        }
        //object_getIvar从Ivar对象中取值
        id propertyVal = object_getIvar(self, ivar);
        NSLog(@"%@----",propertyVal);
        
        //动态的创建类
        //NSClassFromString 把字符串转换成对应的类
        Class varClass = NSClassFromString(className);
        id varobj = [[varClass alloc] init];
        //调用新创建类的方法,这里一定要引入对应的头文件,不然调用方法会错
        //会调用WQClass里面的test方法
        [varobj test];
        
        //class_getInstanceVariable  获取私有变量
        Ivar ivarobj = class_getInstanceVariable(varClass, [@"_age" UTF8String]);
        //object_setIvar赋值函数
        object_setIvar(varobj, ivarobj, age);
        return varobj;
    }
    return nil;
}

@end

测试:
#import "ViewController.h"

#import "WQClass.h"
#import "NSObject+RunTimeTest.h"

@interface ViewController ()

@property (nonatomic,strong)NSString *name;

@end

@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    _name = @"xiaonan";
    WQClass *wq = [self testRunTime:@"WQClass" age:@"20"];
    NSLog(@"age = %@",wq.age);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


/*
结果:
2015-11-09 20:59:03.316 RunTime1[2298:259336] -----name
2015-11-09 20:59:52.909 RunTime1[2298:259336] xiaonan----
2015-11-09 21:01:26.439 RunTime1[2298:259336] 这里是WQClass
2015-11-09 21:02:53.755 RunTime1[2298:259336] age = 20
*/


转载于:https://my.oschina.net/u/2359409/blog/528252

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值