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;
}