Runtime快速上手(1)

依照惯例跳过Runtime的介绍,这里只介绍Runtime的基本用法和简单应用例子。

一、获取属性列表

-(void)getPropertyList
{
    NSLog(@"----------获取属性列表----------");
    unsigned int count;
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    for (NSInteger i = 0 ; i < count; i ++) {
        const char * name = property_getName(propertyList[i]);
        NSLog(@"%@",[NSString stringWithUTF8String:name]);
    }
}

输出结果:

**2016-03-03 10:09:14.529 FL_RUNTIME_DEMO[11547:4314954] ----------****获取属性列表****----------**
**2016-03-03 10:09:14.530 FL_RUNTIME_DEMO[11547:4314954] publicString**
**2016-03-03 10:09:14.530 FL_RUNTIME_DEMO[11547:4314954] inPrivateString**

二、获取变量列表

-(void)getIvarList
{
    NSLog(@"----------获取变量列表----------");
    unsigned int count;
    Ivar *ivarList = class_copyIvarList([self class], &count);
    for (NSInteger i = 0 ; i < count; i ++) {
        const char * name = ivar_getName(ivarList[i]);
        NSLog(@"%@",[NSString stringWithUTF8String:name]);
    }
}

输出结果:

**2016-03-03 10:12:39.179 FL_RUNTIME_DEMO[11584:4318809] ----------****获取变量列表****----------**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] privateString**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] _publicString**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] _inPrivateString**

这里获取的是变量列表,注意_publicString_inPrivateString也是变量

三、获取实例方法列表

-(void)getMethodList
{
    NSLog(@"----------获取实例方法列表----------");
    unsigned int count;
    Method *methodList = class_copyMethodList([self class], &count);
    for (NSInteger i = 0 ; i < count; i ++) {
        SEL name = method_getName(methodList[i]);
        NSLog(@"%@",NSStringFromSelector(name));
    }
}

输出结果:

**2016-03-03 10:17:02.123 FL_RUNTIME_DEMO[11612:4323650] ----------****获取方法列表****----------**
**2016-03-03 10:17:02.124 FL_RUNTIME_DEMO[11612:4323650] getMethodList**
**2016-03-03 10:17:02.124 FL_RUNTIME_DEMO[11612:4323650] testMethodOne**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testMethodTwo**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getPropertyList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getIvarList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getProtocolList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getClassMethod**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testMsgSend**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testAssociatedObject**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testDicToModel**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testMethod**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testCategory**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testMethodRepost**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] publicString**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] setPublicString:**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] inPrivateString**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] setInPrivateString:**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] .cxx_destruct**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] forwardInvocation:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] methodSignatureForSelector:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] forwardingTargetForSelector:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] viewDidLoad**

四、获取类方法列表

-(void)getClassMethod
{
    NSLog(@"----------获取类方法列表----------");
    unsigned int count;
    Method *methodList = class_copyMethodList(objc_getMetaClass(class_getName([self class])), &count);
    for (NSInteger i = 0 ; i < count; i ++) {
        SEL name = method_getName(methodList[i]);
        NSLog(@"%@",NSStringFromSelector(name));
    }
}

输出结果:

**2016-03-03 10:20:31.711 FL_RUNTIME_DEMO[11661:4326710] ----------****获取类方法列表****----------**
**2016-03-03 10:20:31.712 FL_RUNTIME_DEMO[11661:4326710] testClassMethod**
**2016-03-03 10:20:31.712 FL_RUNTIME_DEMO[11661:4326710] resolveInstanceMethod:**

五、获取协议列表

-(void)getProtocolList
{
    NSLog(@"----------获取协议列表----------");
    unsigned int count;
    Protocol * __unsafe_unretained * protocolList =class_copyProtocolList([super class], &count);
    
    for (NSInteger i = 0 ; i < count; i ++) {
        const char* name = protocol_getName(protocolList[i]);
        NSLog(@"%@",[NSString stringWithUTF8String:name]);
    }
}

输出结果:

**2016-03-03 10:21:45.912 FL_RUNTIME_DEMO[11703:4328231] ----------****获取协议列表****----------**
**2016-03-03 10:21:45.914 FL_RUNTIME_DEMO[11703:4328231] UITableViewDataSource**
**2016-03-03 10:21:45.914 FL_RUNTIME_DEMO[11703:4328231] UITableViewDelegate**

六、消息发送

@interface myObject : NSObject

@property(strong,nonatomic)NSString *name;
@property(assign,nonatomic)NSInteger uid;

-(void)testMyObject;
@end

@implementation myObject

-(void)testMyObject
{
    NSLog(@"测试成功");
}
}
@end
.
.
.
-(void)testMsgSend
{
    NSLog(@"----------测试向对象发送消息----------");
    myObject *my = [[myObject alloc] init];
    objc_msgSend(my,@selector(testMyObject));
}

输出结果:

**2016-03-03 10:25:59.154 FL_RUNTIME_DEMO[11744:4332809] ----------****测试向对象发送消息****----------**
**2016-03-03 10:25:59.155 FL_RUNTIME_DEMO[11744:4332809] ****测试成功**

七、关联对象

-(void)testAssociatedObject
{
    NSLog(@"----------测试关联对象----------");
    
    const char * key = "thekey";
    NSString *mykey = objc_getAssociatedObject(self, key);
    if (!mykey) {
        objc_setAssociatedObject(self, key, @"123",OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    NSString *getkey = objc_getAssociatedObject(self, key);
    NSLog(@"%@",getkey);
    
}

输出结果:

**2016-03-03 10:29:24.214 FL_RUNTIME_DEMO[11788:4336028] ----------****测试关联对象****----------**
**2016-03-03 10:29:24.216 FL_RUNTIME_DEMO[11788:4336028] 123**

八、字典转模型

-(void)testDicToModel
{
    NSLog(@"----------测试字典转模型----------");
    
    NSDictionary *dic = @{@"name":@"jack",@"uid":@123};
    
    myObject *my = [[myObject alloc] init];
    
    [dic enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL * stop) {
        //获得属性对象
        objc_property_t property = class_getProperty([my class], key.UTF8String);
        //获取属性名称
        NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
        //获得属性attr
//        const char * attr = property_getAttributes(property);
//        NSString *attrs = [NSString stringWithUTF8String:attr];
        
        //设置对应属性对应值
        [my setValue:value forKey:propertyName];
    }];
    
    NSLog(@"name = %@,uid = %ld",my.name,my.uid);
}

输出结果:

**2016-03-03 10:31:54.336 FL_RUNTIME_DEMO[11819:4338148] ----------****测试字典转模型****----------**
**2016-03-03 10:31:54.337 FL_RUNTIME_DEMO[11819:4338148] name = jack,uid = 123**

九、method相关函数

-(void)testMethodOne
{
    NSLog(@"这是函数1");
}

-(void)testMethodTwo
{
    NSLog(@"这是函数2");
}

-(void)testMethod
{
    NSLog(@"----------测试method相关函数----------");
    Method method1 = class_getInstanceMethod([self class], @selector(testMethodOne));
    Method method2 = class_getInstanceMethod([self class], @selector(testMethodTwo));
    method_exchangeImplementations(method1, method2);
    NSLog(@"调用methodOne输出:");
    [self testMethodOne];
    NSLog(@"调用methodTwo输出:");
    [self testMethodTwo];
    
    IMP imp = method_getImplementation(method1);
    method_setImplementation(method2, imp);
    NSLog(@"重新设置method2的imp后调用methodTwo输出:");
    [self testMethodTwo];
    NSLog(@"这时method1的输出是:");
    [self testMethodOne];
    
    BOOL isequal = sel_isEqual(method_getName(method1), method_getName(method2));
    NSLog(@"是否相同:%d",isequal);
    
}

输出结果:

**2016-03-03 10:33:42.975 FL_RUNTIME_DEMO[11857:4340224] ----------****测试****method****相关函数****----------**
**2016-03-03 10:33:42.976 FL_RUNTIME_DEMO[11857:4340224] ****调用****methodOne****输出****:**
**2016-03-03 10:33:42.976 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****调用****methodTwo****输出****:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****1**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****重新设置****method2****的****imp****后调用****methodTwo****输出:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这时****method1****的输出是:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****是否相同:****0**

你可能感兴趣的:(Runtime快速上手(1))