Что происходит при наблюдении UIApplicationDidEnterBackgroundNotification на старой iOS без многозадачности? - PullRequest
0 голосов
/ 13 сентября 2011

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

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

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

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

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

Ответы [ 4 ]

3 голосов
/ 13 сентября 2011

Вы должны проверить, является ли версия 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.

1 голос
/ 19 апреля 2013

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

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

0 голосов
/ 13 сентября 2011

Фоновая обработка (т.е. многозадачность) не существовала до 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];
0 голосов
/ 13 сентября 2011

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

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