首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现UIApplicationDelegate协议方法?

如何实现UIApplicationDelegate协议方法?
EN

Stack Overflow用户
提问于 2013-11-21 01:42:26
回答 1查看 1.1K关注 0票数 0

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

代码语言:javascript
复制
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
   ...
}

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

我考虑过使用一个类别来扩展应用程序,但是类别文档中的这一行值得关注:

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

问题是,如何在我的模块中实现协议方法,以便iOS知道在适当的时候调用我的协议方法?

EN

回答 1

Stack Overflow用户

发布于 2013-11-21 02:52:11

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

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

首先,您需要导入类:

代码语言:javascript
复制
#import <objc/runtime.h>

然后,您需要声明object方法的结构:

代码语言:javascript
复制
struct objc_method {
    SEL method_name;
    char *method_types;
    IMP method_imp;
};

最后,您可以通过以下方式更改实现:

代码语言:javascript
复制
//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,您可以为方法分配内存,并在以后将其添加到类中:

代码语言:javascript
复制
//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;
    }

将方法添加到类中:

代码语言:javascript
复制
if (!existMethod) {
        class_addMethod([[[UIApplication sharedApplication] delegate] class], openURLMethod->method_name, openURLMethod->method_imp, openURLMethod->method_types);
    }

但问题是,我想,当应用程序启动时,操作系统正在注册该方法,因此,如果应用程序启动时该方法不存在,操作系统将永远不会调用您的方法。

我将研究操作系统是如何管理事件的。对于applicationDidEnterBackground,如果您没有AppDelegate上的实现并在运行时添加它,操作系统就不会调用您的实现。这就是为什么我假设操作系统在应用程序启动时注册事件的原因。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20110879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档