我有3天的问题:(我想在CLLocationManagerDelegate协议中挂钩这个方法:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
我尝试了一切但没有成功。我知道如何挂钩到类或框架,但我找不到挂钩委托的解决方案。 请帮我! 感谢
答案 0 :(得分:4)
挂钩需要您提供想要挂钩的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
填充objc_getClassList(list, numClasses)
类型的对象。
在所有这些类中搜索符合CLLocationManagerDelegate
协议并实现locationManager:didUpdateLocations:
方法的类。如果我们发现了一个我们用自己的实现挂钩它。
在我们自己的实现中,我们打印一些调试消息并在返回之前调用原始实现。当然,你可以做任何事情,这只是一个例子。
使用free(list)
释放已分配的内存。