NSNotificationCenter代码适用于iPhone,但不适用于iPad

时间:2011-03-23 19:37:49

标签: iphone ios ipad

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

为什么此代码适用于iPhone模拟器但不适用于iPad模拟器?我在这段代码上得到EXC_BAD_ACCESS。尝试版本iOS 3.2,4.2,4.3。

1 个答案:

答案 0 :(得分:-1)

要扩展主要Izzy的评论,UIApplicationDidEnterBackgroundNotification被定义为extern NSString *。通常最好定义常量字符串,而不是:

#define UIApplicationDidEnterBackgroundNotification @"whatever"

因为它允许你通过身份而不是相等来测试,因为用户引用UIApplicationDidEnterBackgroundNotification的所有尝试都将引用它的相同实例,而不仅仅是(可能受编译器命令)单独的NSStrings与它相同值。

UIApplicationDidEnterBackgroundNotification的实际值包含在UIKit中,因此当加载UIKit库时,指针将被填充。问题是iOS 3.2没有定义UIApplicationDidEnterBackgroundNotification,所以你最终得到的是一个未定义的指针。因此,您将未定义的指针传递给NSNotificationCenter,在尝试读取时会导致崩溃。

聪明的事情可能是:

UIDevice *currentDevice = [UIDevice currentDevice];

if( [currentDevice respondsToSelector:@selector(isMultitaskingSupported)] && 
    [currentDevice isMultitaskingSupported])
{
    [[NSNotificationCenter defaultCenter] addObserver:self 
                              selector:@selector(didEnterBackground:)
                              name:UIApplicationDidEnterBackgroundNotification
                              object:nil];
}

因此,检查此设备上的UIDevice类的版本是否知道多任务处理是否可能,如果是,则检查是否支持多任务处理。标准C快捷键评估意味着&&和只有在它之前的东西成功时才会被评估,因此不会意外地发出无法识别的方法调用。

只有支持多任务处理才能注册通知。这是安全的,因为UIApplicationDidEnterBackgroundNotification字符串是在多任务处理的同时引入的。没有设备支持多任务处理,也没有提供字符串。