Что происходит при наблюдении UIApplicationDidEnterBackgroundNotification на старой iOS без многозадачности?

У меня есть эта строка кода:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:UIApplicationDidEnterBackgroundNotification object:nil];

Прекрасно работает в симуляторе iPhone 4.3 и на моем iPhone под управлением 4.x. Однако происходит сбой на iPhone под управлением 3.x. Имеет смысл. Я предполагаю, что эта строка кода не работает, когда нет многозадачности.

Мне сложно отлаживать, потому что человек, который тестирует меня с системой 3.x, находится в удаленном месте. Я даже не уверен, оценивает ли символ UIApplicationDidEnterBackgroundNotification правильную строку, или ноль, или случайную неинициализированную память, или что в этой ОС.

Но кроме того, чтобы выяснить, почему это терпит неудачу, что я могу сделать с некоторым усилием, что я должен делать? Как определить, существует ли конкретное уведомление, прежде чем я его увижу? Или я проверяю, доступна ли многозадачность как общая категория? Я думаю, я думал, что строка кода будет в безопасности. Если ОС никогда не генерирует это уведомление, я не получаю уведомление, но линия не должна падать.

4 ответа

Решение

Вы должны проверить, является ли версия iOS 4.0 или более поздней при компиляции (для этого есть встроенный препроцессор #defines), а также проверить поддержку многозадачности (в случае, если она отключена на устройстве, если в противном случае она будет поддерживаться):

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
    if([[UIDevice currentDevice]
        respondsToSelector:@selector(isMultitaskingSupported)] &&
       [[UIDevice currentDevice] isMultitaskingSupported])
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:UIApplicationDidEnterBackgroundNotification object:nil];
    }
#endif

Вам не нужно использовать #if, но он сохраняет компиляцию в дополнительных проверках, которые, как вы знаете, всегда будут возвращать false.

Просто для вашего понимания, проблема возникает не столько при регистрации неизвестного уведомления, сколько в том, что имя уведомления не существует (как вы подозревали), и на самом деле дело даже не в том, что UIApplicationDidEnterBackgroundNotification является NULL, но по факту &UIApplicationDidEnterBackgroundNotificationявляется NULL; это то, как вы проверяете это, на самом деле.

Итак, что происходит (случилось) в вашем случае, это просто NULL разыменование, NSNotificationCenter даже не вмешивался.

Я думаю, что это будет работать для вас, я не проверял.

#ifdef _USE_OS_4_OR_LATER
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:UIApplicationDidEnterBackgroundNotification object:nil];
#endif

Фоновая обработка (т.е. многозадачность) не существовала до 4.0. Регистрация в несуществующем уведомлении не должна причинять много вреда. Я ожидал бы, что это просто никогда не будет вызвано. Но я признаю, что я не проверял это с уведомлениями.

Приведенный ниже пример проверяет во время выполнения версию os (здесь 4.0 и 3.2), затем выполняет тот или иной метод.

NSString *requiredSystemVersion = @"4.0"; 
NSString *currentSystemVersion = [[UIDevice currentDevice] systemVersion];
if (![currentSystemVersion compare:requiredSystemVersion options:NSNumericSearch] != NSOrderedAscending) [self do4dotXStuff];

requiredSysVer = @"3.2";
if ([currentSystemVersion compare:requiredSystemVersion options:NSNumericSearch] != NSOrderedAscending) [self do3dotTwoStuff];
Другие вопросы по тегам