gpt4 book ai didi

ios - 如何实现 UIApplicationDelegate 的协议(protocol)方法?

转载 作者:行者123 更新时间:2023-11-29 03:28:41 26 4
gpt4 key购买 nike

我在一个类中工作,称之为模块,我需要在 AppDelegate 中实现这个方法:

- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
...
}

我知道哪个类是 AppDelegate(称之为 App),但我无权编辑该类。如何从我的模块中实现委托(delegate)方法?

我考虑过使用类别来扩展应用程序,但是 category docs 中的这一行是一个问题:

“您需要在任何您希望使用附加方法的源代码文件中导入类别头文件,否则您将遇到编译器警告和错误。”

问题是,我如何才能以某种方式在我的模块中实现协议(protocol)方法,以便 iOS 知道在适当的时间调用我的协议(protocol)方法?

最佳答案

好的,乔...如果您想从另一个模块实现 application:openURL:sourceApplication:annotation:,您可以在运行时执行。

我们需要假设 AppDelegate 已经实现了该方法

首先您需要导入类:

#import <objc/runtime.h>

然后您需要声明对象方法的结构:

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 上没有实现并且在运行时添加它,则操作系统永远不会调用您的实现。这就是为什么我假设操作系统在应用程序启动时注册事件。

关于ios - 如何实现 UIApplicationDelegate 的协议(protocol)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20110879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com