你可以调整应用程序:didReceiveRemoteNotification:

时间:2013-12-09 23:41:13

标签: ios iphone objective-c swizzling

我目前正在开发一款需要调整AppDelegate应用程序的产品:didReceiveRemoteNotification :(我不想在appDelegate本身调用我的新方法)。

事情是:调酒根本不起作用。在成功之前,我已经多次调过方法,而这一次,替换实现根本就没有被调用。我想知道这是否是因为appDelegate方法的一些特殊性,因为它们是由系统调用的,而不是应用程序。

1 个答案:

答案 0 :(得分:4)

我将假设您的问题中缺少的大部分内容,如果可能的话,始终使用代码示例发布问题是一个好主意。

  1. 您需要确保在UIApplicationDelegate的特定实现上调整方法,而不是UIApplicationDelegate本身。对于Eg

    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    @end
    

    在这种情况下,您需要调动AppDelegate类。

  2. 此外,如果您正在尝试编写静态库/框架,则可能根本不知道此类的名称。在这种情况下,最简单/最安全的方法是询问App的AppDelegate名称并使用它来通过NSClassFromString()检索特定的类实例,或者你可以通过暴力来找到你需要的类(因为你通常有一个Single AppDelegate类)。

        unsigned int numberOfClasses = 0;
        Class *classes = objc_copyClassList(&numberOfClasses);
        Class appDelegateClass = nil;
        for (unsigned int i = 0; i < numberOfClasses; ++i) {
            if (class_conformsToProtocol(classes[i], @protocol(UIApplicationDelegate))) {
                appDelegateClass = classes[i];
            }
    }
    
  3. 修改

    上述方法存在一些缺点,

    1. 它遍历应用程序代码可访问的所有类,循环遍历所有这些类并不是一个高性能的解决方案。

    2. 许多着名的SDK会调动或动态扩展您的AppDelegate,因为在这个地方可以拦截很多有趣的东西。这也意味着您的应用程序可能有多个UIApplicationDelegate协议的实现,上面的代码可能只选择它的任何实现,导致一些严重的问题。

    3. 正如克里斯在下面的评论中所建议的那样,使用[[UIApplication sharedApplication].delegate class]更加安全和高效。在调用这行代码时,它应该为您提供iOS应用程序已知的确切AppDelegate实现。