Ios 您是否可以swizzle应用程序:DidReceivereMotonification:

Ios 您是否可以swizzle应用程序:DidReceivereMotonification:,ios,iphone,objective-c,swizzling,Ios,Iphone,Objective C,Swizzling,我目前正在开发一个需要关闭AppDelegate应用程序的产品:DidReceiveMemoteNotification:(我不想在AppDelegate本身中调用我的新方法) 问题是:这根本不起作用。我之前已经成功地使用了好几次方法,这次,根本没有调用替换实现。我想知道这是否是因为appDelegate方法的某些特殊性,因为这些方法是由系统调用的,而不是由应用程序调用的 我将假设您的问题中缺少的大部分内容,如果可能的话,总是用代码示例发布问题是一个好主意 您需要确保在UIApplication

我目前正在开发一个需要关闭AppDelegate应用程序的产品:DidReceiveMemoteNotification:(我不想在AppDelegate本身中调用我的新方法)


问题是:这根本不起作用。我之前已经成功地使用了好几次方法,这次,根本没有调用替换实现。我想知道这是否是因为appDelegate方法的某些特殊性,因为这些方法是由系统调用的,而不是由应用程序调用的

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

  • 您需要确保在UIApplicationLegate的特定实现上滑动方法,而不是在UIApplicationLegate本身上滑动方法。例如

    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    @end
    
    @接口AppDelegate:UIResponder
    @结束
    
    在这种情况下,您需要swizzle AppDelegate类

  • 另外,如果您试图编写一个静态库/框架,您可能根本不知道这个类的名称。在这种情况下,最简单/最安全的方法是请求应用程序的AppDelegate名称,并使用该名称通过NSClassFromString()检索特定的类实例,或者您可以使用蛮力来查找所需的类(因为您通常只有一个AppDelegate类)

    unsigned int numberOfClasses=0;
    Class*classes=objc_copyClassList(&numberOfClasses);
    类appDelegateClass=nil;
    for(无符号整数i=0;i
  • 编辑

    上述方法有一些缺点

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

  • 许多著名的SDK都会快速或动态地扩展您的
    AppDelegate
    ,因为在这个地方可以截获很多有趣的东西。这也意味着您的应用程序可能有多个
    uiapplicationelegate
    协议的实现,上面的代码可能只是选择了它的任何实现,从而导致一些严重问题


  • 正如Chris在下面的评论中所建议的,只使用
    [[UIApplication sharedApplication].delegate类]
    更安全、更高效。在调用这行代码时,您应该知道iOS应用程序所知道的确切的AppDelegate实现。

    我认为苹果公司不喜欢您Swizzing他们的API:根据定义,您在自己的应用程序中拥有AppDelegate的实现,因此Swizzing是不必要的。现在,如果您正在谈论swizzle其他应用程序的实现,那么,不,您不能这样做。在您定义的类中swizzle方法没有多大意义。如果您不想在应用程序委托中使用代码,请将其放在从那里调用的其他方法中,或者发布其他对象收到的通知。@Alex,您共享的链接不适用于此问题,因为问题清楚地表明,它试图交换application:didReceiveMemotentification:这不是Apple实现的,它是一个有文档记录的回调而不是一个实现(不像你的链接提到的dealloc)。为什么不直接使用
    [[UIApplication sharedApplication].delegate class]
    ?@ChrisH,使用你共享的方式更安全、更高效,我应该相应地更新我的答案。
        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];
            }
    }