Как обработать UIApplicationWillTerminateNotification в IOS4? - PullRequest
1 голос
/ 28 июня 2011

В iOS4 я регистрирую следующее уведомление:

[[NSNotificationCenter defaultCenter]   addObserver:self
                                                 selector:@selector(appWillTerminate:)
                                                 name:UIApplicationWillTerminateNotification
                                                 object:[UIApplication sharedApplication]];

-(void)appWillTerminate:(UIApplication *) app {
    NSLog(@"terminate");
}

Я знаю, что это вызывается не во всех ситуациях, как в предыдущих версиях iOS, однако просто зарегистрировав это, я получаю1004 * при выходе из приложения.Тем не менее, я не могу удалить его, потому что мое приложение поддерживает iOS3.0 +.Как я могу справиться с этим?

ОБНОВЛЕНИЕ: Вот журнал сбоев:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000011
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x0000441c objc_msgSend + 20
1   Foundation                      0x00015432 _nsnote_callback + 150
2   CoreFoundation                  0x000271da __CFXNotificationPost_old + 390
3   CoreFoundation                  0x00026e7a _CFXNotificationPostNotification + 122
4   Foundation                      0x00004720 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64
5   Foundation                      0x0000de3a -[NSNotificationCenter postNotificationName:object:] + 14
6   UIKit                           0x000bef10 -[UIApplication _terminateWithStatus:] + 164
7   UIKit                           0x000be1b0 -[UIApplication _handleApplicationSuspend:eventInfo:] + 1980
8   UIKit                           0x0007e4a0 -[UIApplication handleEvent:withNewEvent:] + 3620
9   UIKit                           0x0007d470 -[UIApplication sendEvent:] + 60
10  UIKit                           0x0007ccf8 _UIApplicationHandleEvent + 6804
11  GraphicsServices                0x00005dd8 PurpleEventCallback + 1024
12  CoreFoundation                  0x00035e40 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 22
13  CoreFoundation                  0x00035dfe __CFRunLoopDoSource1 + 158
14  CoreFoundation                  0x0002809e __CFRunLoopRun + 574
15  CoreFoundation                  0x00027d74 CFRunLoopRunSpecific + 220
16  CoreFoundation                  0x00027c82 CFRunLoopRunInMode + 54
17  GraphicsServices                0x00004e84 GSEventRunModal + 188
18  UIKit                           0x00004f8c -[UIApplication _run] + 564
19  UIKit                           0x000024cc UIApplicationMain + 964

Ответы [ 3 ]

1 голос
/ 28 июня 2011

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

//YourClass
-(id)init
{
    if((self = [super init]))
    {
        [[NSNotificationCenter defaultCenter]   addObserver:self
                                             selector:@selector(appWillTerminate:)
                                             name:UIApplicationWillResignActiveNotification
                                             object:[UIApplication sharedApplication]];
    }
    return self;
}

-(void)appWillTerminate:(NSNotification *)note {
    NSLog(@"terminate");
}

-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    //Other releases
    [super dealloc];
}
0 голосов
/ 28 июня 2011

Первый аргумент, переданный вашему методу appWillTerminate:, будет NSNotification объектом, а не вашим UIApplication. См. Ссылка класса NSNotificationCenter

0 голосов
/ 28 июня 2011

Что вы можете сделать, это определить версию iOS, и если ее версия v. 3.0, используйте appWillTerminate, а если ее версия 4.0 - appWillResignActive или appDidEnterBackground, пример:

NSString *ver = [[UIDevice currentDevice] systemVersion];
if([ver isEqualToString:@"3.0"]){
    //Device is running 3.0
    [[NSNotificationCenter defaultCenter]   addObserver:self
                                             selector:@selector(appWillTerminate:)
                                             name:UIApplicationWillTerminateNotification
                                             object:[UIApplication sharedApplication]];
}
else if([ver isEqualToString:@"4.0"]){
    //4.0
    [[NSNotificationCenter defaultCenter]   addObserver:self
                                             selector:@selector(appWillTerminate:)
                                             name:UIApplicationWillResignActiveNotification
                                             object:[UIApplication sharedApplication]];
}
...