如何在IOS4中处理UIApplicationWillTerminateNotification?

时间:2011-06-28 16:47:24

标签: iphone objective-c ipad ios4 nsnotificationcenter

在iOS4中,我正在注册以下通知:

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

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

我知道在iOS版本的所有情况下都没有调用它,但是,只需注册这个,我就会在应用程序退出时得到EXC_BAD_ACCESSS。不过,我无法删除它,因为我的应用程序支持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 个答案:

答案 0 :(得分:1)

确保在正在侦听终止通知的任何类中删除观察者。如果您没有删除通知,它将尝试将其发布到解除分配的对象,然后您的应用程序将崩溃。你不应该因为收听不存在的通知而崩溃,它不会被调用。

//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];
}

答案 1 :(得分:0)

你可以做的是检测iOS版本,如果它的v.3.0然后使用appWillTerminate,如果它的v.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]];
}

答案 2 :(得分:0)

传递给appWillTerminate:方法的第一个参数将是NSNotification对象,而不是UIApplication。见the NSNotificationCenter Class Reference