Objective-C runtime(二)

上一篇我们通过runtime获取了Objective-C的类的相关信息,现在我们来修改、添加类。

首先来添加成员变量。之前我们获取了很多关于成员变量的信息,但是添加成员变量并不是ivar或property相关的函数,而是associatedObject相关的函数。

const char* str_key="str key";
NSString* tmp=@"tmp str";

objc_setAssociatedObject(l,str_key,tmp,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

NSString* tmp2=(NSString*)objc_getAssociatedObject(l, str_key);

objc_removeAssociatedObjects(l);

熟悉C++的同学应该都了解多态,这是C++的OOP编程的核心之一。如果我们需要在运行时动态地添加、修改某个方法,需要怎么做?策略模式?在Objective-C中我们可以通过runtime直接添加、修改方法。

① 动态添加方法

这是我们要添加的一个方法:

void add_func(id _self,SEL _cmd,NSString* _str)
{
    NSLog(@"add_func:%@\n",_str);
}

添加的代码如下:

class_addMethod([MyClass class], @selector(addFunc), (IMP)add_func, "v@:@");

[m performSelector:@selector(addFunc) withObject:@"tmp5"];
    
objc_msgSend(m, @selector(addFunc), @"tmp6");

id (*imp)(id,SEL,id)=(id (*)(id,SEL,id))[m methodForSelector:@selector(addFunc)];
imp(l,@selector(addFunc),@"tmp7");

通过class_addMethod函数可以添加方法,其中最后一个参数是标示方法的返回值与参数的。常用的如下:

v  void
@ id
: SEL
# Class
* char*

调用添加的方法不能直接使用[m addFunc]要通过runtime的performSelector,当然也能通过更基础的objec_msgSend函数或者IMP来调用。

②修改类的方法

//获得实例方法
Method func1=class_getInstanceMethod([m class], @selector(func1));
    
Method func2=class_getInstanceMethod([MyClass class], @selector(func2));
    
method_exchangeImplementations(func1, func2);
    
 //获得类方法
Method func3=class_getClassMethod([m class], @selector(func3));
    
Method func4=class_getClassMethod([MyClass class], @selector(func4));
    
method_exchangeImplementations(func3, func4);

上面的代码是交换了func1、func2两个实例方法以及func3、func4两个类方法。我们也可以通过method_setImplementation函数修改method的IMP。

runtime常见的用法就是这些,更多的函数可以在之前提到的头文件中搜索或者在Xcode中键入class、method等相关前缀来查询。

如有错误,欢迎指出!

你可能感兴趣的:(Objective-C runtime(二))