挂钩要求您提供想要挂钩的 Objective-C 类。这是什么Class
类型是为了.获取 obj-c 类的一种方法是通过名称objc_getClass
功能。但就你的情况而言,据我正确理解,你没有名字。你想要挂钩每个符合以下条件的类CLLocationManagerDelegate
协议并实现具体方法。这是您可以做的。
您可以获取每个已注册的 obj-C 类并搜索符合以下条件的类CLLocationManagerDelegate
像这样的协议:
static IMP original_didUpdateLocations;
void replaced_didUpdateLocations(id self, SEL _cmd, CLLocationManager* manager, NSArray* locations)
{
NSLog(@"%@ did update locations to %@", manager, locations);
original_didUpdateLocations(self, _cmd, manager, locations);
}
...
#import <objc/runtime.h>
int numClasses = objc_getClassList(NULL, 0);
Class* list = (Class*)malloc(sizeof(Class) * numClasses);
objc_getClassList(list, numClasses);
for (int i = 0; i < numClasses; i++)
{
if (class_conformsToProtocol(list[i], @protocol(CLLocationManagerDelegate)) &&
class_getInstanceMethod(list[i], @selector(locationManager:didUpdateLocations:)))
{
MSHookMessageEx(list[i], @selector(locationManager:didUpdateLocations:), (IMP)replaced_didUpdateLocations, (IMP*)&original_didUpdateLocations);
}
}
free(list);
我们需要知道有多少个班级。objc_getClassList(NULL, 0)
返回所有注册类的数量。
分配内存与malloc(sizeof(Class) * numClasses)
并用类型的对象填充它Class
using objc_getClassList(list, numClasses)
.
在所有这些类中搜索符合以下条件的类CLLocationManagerDelegate
协议和实施locationManager:didUpdateLocations:
方法。如果我们找到了一个,我们就会将它与我们自己的实现挂钩。
在我们自己的实现中,我们打印一些调试消息并在返回之前调用原始实现。当然,你可以做任何你想做的事,这只是一个例子。
使用释放分配的内存free(list)
.