iOS Runtime的使用

2018-03-08  本文已影响4人  和谐共处

导入头文件#import <objc/runtime.h>

为类别添加属性

//Person.h

#import "Person.h"

@interface Person (Children)

@property (nonatomic,copy) NSString *schoolName;

@end

//Person.m
#import "Person+Children.h"
#import <objc/runtime.h>
void * kSchoolNameKey = "SchoolNameKey";
@implementation Person (Children)

//动态为Category扩展加属性
- (void)setSchoolName:(NSString *)schoolName
{
    objc_setAssociatedObject(self, kSchoolNameKey, schoolName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)schoolName
{
    return objc_getAssociatedObject(self, kSchoolNameKey);
}
@end

一些常用方法

#pragma mark - 获取所有变量

- (void)getAllIVar:(Class)class{
    unsigned int count = 0;
    Ivar *ivar = class_copyIvarList(class, &count);
    for (int i = 0 ; i<count; i++)
    {
        Ivar var = ivar[i];
        const char *varName = ivar_getName(var);
        NSString *name = [NSString stringWithUTF8String:varName];
        const char *type = ivar_getTypeEncoding(var);
        NSLog(@"%@ =============== %s",name,type);
    }
    free(ivar);
    
}
#pragma mark - 获取所有属性
- (void)getAllPropertys:(Class)class{
    unsigned int count;
    objc_property_t *pt = class_copyPropertyList(class, &count);
    for (int i=0; i<count; i++) {
        objc_property_t property = pt[i];
        const char *property_name = property_getName(property);
        NSLog(@"property_name==%s",property_name);
        
    }
}
#pragma mark - 获取所有方法
- (void)getAllFunction:(Class)class{
    unsigned int count;
    Method *methods =class_copyMethodList(class, &count);
    for (int i=0; i<count; i++) {
        Method method = methods[i];
        SEL selector = method_getName(method);
        NSString *method_name = NSStringFromSelector(selector);
        const char *type = method_getTypeEncoding(method);
        NSLog(@"method_name=%@,type=%s",method_name,type);
         NSMethodSignature *methodSig = [class instanceMethodSignatureForSelector:selector];
        NSLog(@"arg0==%s",[methodSig getArgumentTypeAtIndex:0]);

        
    }
}
#pragma mark -  动态变量控制
- (void)controlVar{
    
    _person.name = @"小明";
    NSLog(@"名字是:%@",_person.name );
    _person.schoolName = @"小学";
    NSLog(@"学校是:%@",_person.schoolName);
    unsigned int count = 0;
    Ivar *ivar = class_copyIvarList(_person.class, &count);
    for (int i = 0 ; i<count; i++)
    {
        Ivar var = ivar[i];
        const char *varName = ivar_getName(var);
        NSString *name = [NSString stringWithUTF8String:varName];
        NSLog(@"var_name==%@",name);
        if ([name isEqualToString:@"_name"])
        {
            object_setIvar(_person, var, @"小花");
            
        }
        
    }
    free(ivar);
    NSLog(@"名字是1:%@",_person.name);
    NSLog(@"学校是1:%@",_person.schoolName);

}
#pragma mark -  交换方法
- (void)changeMethod
{
    Method m1 = class_getInstanceMethod(_person.class, @selector(goHome));
    Method m2 = class_getInstanceMethod(_person.class, @selector(goToBed));
    method_exchangeImplementations(m1, m2);
    
    [_person goHome];
    
}
#pragma mark -  动态添加方法
- (void)addMethod
{
    IMP method = [self methodForSelector:@selector(hqImplement)];
    NSMethodSignature *sl;
    class_addMethod(_person.class, @selector(walk),(IMP)walk, "v@:");
    if ([_person respondsToSelector:@selector(walk)]) {
        
        [_person performSelector:@selector(walk)];
        
    } else{
        NSLog(@"Sorry,I don't know");
    }
}
- (void)hqImplement{
    NSLog(@"hqImplement添加的方法 @selector(walk)哈哈哈");
    
}
void walk(id self,SEL _cmd){

    NSLog(@"动态添加的方法 @selector(walk)----");
    NSLog(@"_cmd==%@",NSStringFromSelector(_cmd));
}
#pragma mark - 解决未找到方法的崩溃
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    IMP impBlock = imp_implementationWithBlock(^(id self, NSString *word) {
        NSLog(@"method resolution way : send message = %@", word);
    });
   
    if (sel == @selector(sendMessage:))
    {
        class_addMethod([self class], sel, impBlock, "v@*");
    }
    
    return YES;
}
上一篇 下一篇

猜你喜欢

热点阅读