我在一个类中工作,称为模块,我需要在AppDelegate中实现这个方法:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
...
}我知道哪个类是AppDelegate (称为App),但我没有编辑该类的权限。如何从我的模块实现委托方法?
我考虑过使用一个类别来扩展应用程序,但是类别文档中的这一行值得关注:
“您需要在任何希望使用其他方法的源代码文件中导入类别头文件,否则会遇到编译器警告和错误。”
问题是,如何在我的模块中实现协议方法,以便iOS知道在适当的时候调用我的协议方法?
发布于 2013-11-21 02:52:11
好了乔..。如果要从另一个模块实现application:openURL:sourceApplication:annotation:,可以在运行时执行。
我们需要假设AppDelegate已经实现了TEH方法
首先,您需要导入类:
#import <objc/runtime.h>然后,您需要声明object方法的结构:
struct objc_method {
SEL method_name;
char *method_types;
IMP method_imp;
};最后,您可以通过以下方式更改实现:
//Create the selector of the method.
NSString * openURL = @"application:openURL:sourceApplication:annotation:";
SEL selectorOpenURL = NSSelectorFromString(openURL);
//Get the method of the intance.
Method openURLMethod = class_getInstanceMethod([[[UIApplication sharedApplication] delegate] class], selectorOpenURL);
//Get the current implementation.
IMP openURLIMP = openURLMethod->method_imp;
//Create your own implementation.
IMP myOpenURLIMP = imp_implementationWithBlock(^BOOL(id _s, UIApplication * app,NSURL *url,NSString *sourceApplication,id annotation) {
//Call the original implementation.
openURLIMP(_s,selectorOpenURL,app,url,sourceApplication,annotation);
//Here your implementation code.
NSLog(@"Handling the URL");
return YES;
});但要小心。如果您查看我的代码,我将调用我的实现中的原始实现,因此如果我执行代码以更改多个实现,我的实现将是一个初始(就像电影,我在实现中的实现,实现中的实现,等等)。
编辑:
可以将您的实现添加到类中:
如果class_getInstanceMethod返回null,您可以为方法分配内存,并在以后将其添加到类中:
//If the method dont exist. We need to create one.
if (!openURLMethod) {
existMethod = NO;
openURLMethod = malloc(sizeof(struct objc_method));
openURLMethod->method_types = "c24@0:4@8@12@16@20";
openURLMethod->method_name = selectorOpenURL;
}将方法添加到类中:
if (!existMethod) {
class_addMethod([[[UIApplication sharedApplication] delegate] class], openURLMethod->method_name, openURLMethod->method_imp, openURLMethod->method_types);
}但问题是,我想,当应用程序启动时,操作系统正在注册该方法,因此,如果应用程序启动时该方法不存在,操作系统将永远不会调用您的方法。
我将研究操作系统是如何管理事件的。对于applicationDidEnterBackground,如果您没有AppDelegate上的实现并在运行时添加它,操作系统就不会调用您的实现。这就是为什么我假设操作系统在应用程序启动时注册事件的原因。
https://stackoverflow.com/questions/20110879
复制相似问题