Можете ли вы прокрутить приложение: didReceiveRemoteNotification:

В настоящее время я работаю над продуктом, который должен качнуть приложение AppDelegate:didReceiveRemoteNotification: (я не хочу вызывать свой новый метод в самом appDelegate).

Дело в том, что swizzling просто не работает. Я уже несколько раз успешно прокручивал методы, и на этот раз замещающая реализация просто не вызывается. Мне было интересно, было ли это из-за некоторой специфики методов appDelegate, поскольку они вызываются системой, а не приложением.


person P. Unto    schedule 09.12.2013    source источник
comment
Я не думаю, что Apple нравится, когда вы крутите их API: .com/questions/7720947/method-swizzling-in-ios-5   -  person Alex Wayne    schedule 10.12.2013
comment
По определению, вы владеете реализацией делегата приложения в своем собственном приложении, поэтому swizzling не нужен. Теперь, если вы говорите об изменении реализации другого приложения, то нет, вы не можете этого сделать.   -  person bbum    schedule 10.12.2013
comment
Нет особого смысла использовать метод в классе, который вы определяете. Если вам не нужен код в делегате приложения, поместите его в какой-либо другой метод, который вы вызываете оттуда, или опубликуйте уведомление, которое получает какой-либо другой объект.   -  person Tom Harrington    schedule 10.12.2013
comment
@Alex, ссылка, которой вы поделились, не применима к этому вопросу, поскольку в вопросе четко указано, что он пытается обменять application:didReceiveRemoteNotification: который не реализован Apple, это задокументированный обратный вызов, а не реализация (в отличие от Dealloc, как упоминается в вашей ссылке. )   -  person Saumitra R. Bhave    schedule 03.11.2015


Ответы (1)


Я собираюсь предположить, что большинство вещей, которые отсутствуют в вашем вопросе, это отличная идея всегда публиковать вопросы с примерами кода, когда это возможно.

  1. Вы должны убедиться, что вы используете свои методы для конкретной реализации UIApplicationDelegate, а НЕ самого UIApplicationDelegate. Например

    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    @end
    

    В этом случае вам нужно использовать класс AppDelegate.

  2. Кроме того, если вы пытаетесь написать статическую библиотеку/фреймворк, вы можете вообще не знать имя этого класса. В таких случаях самый простой/безопасный способ - запросить имя приложения AppDelegate и использовать его для получения определенного экземпляра класса через NSClassFromString(), или вы можете просто перебором найти нужный вам класс (потому что у вас обычно есть один класс 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];
            }
    }
    

ИЗМЕНИТЬ

У описанного выше подхода есть несколько недостатков,

  1. Он выполняет итерацию по всем классам, доступным вашему коду приложения, циклическое перебор всех этих классов не является эффективным решением.

  2. Многие известные SDK будут расширять или динамически расширять ваш AppDelegate, потому что в этом одном месте можно перехватить много интересного. Это также означает, что ваше приложение может иметь более одной реализации протокола UIApplicationDelegate, и приведенный выше код может просто выбрать любую его реализацию, что вызовет серьезные проблемы.

Как Крис предложил в комментариях ниже, гораздо безопаснее и эффективнее просто использовать [[UIApplication sharedApplication].delegate class]. который должен дать вам точную реализацию AppDelegate, известную приложению iOS в момент вызова этой строки кода.

person Saumitra R. Bhave    schedule 03.11.2015
comment
Почему бы просто не использовать [[UIApplication sharedApplication].delegate class]? - person ChrisH; 22.05.2017
comment
@ChrisH, гораздо безопаснее и эффективнее использовать то, как вы поделились, я должен соответствующим образом обновить свой ответ. - person Saumitra R. Bhave; 23.05.2017