简体   繁体   中英

NSNotificationCenter Code works in iPhone but not on iPad

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

Why does this code work on iPhone simulator but not on iPad simulator? I get EXC_BAD_ACCESS on this code. Tried version iOS 3.2, 4.2, 4.3.

To expand on Chiefly Izzy's comment, UIApplicationDidEnterBackgroundNotification is defined as an extern NSString * . It's often preferable to define constant strings that way, rather than as:

#define UIApplicationDidEnterBackgroundNotification @"whatever"

Because it allows you to test by identity rather than equality, because all attempts by the user to refer to UIApplicationDidEnterBackgroundNotification will refer to the same instance of it, not just to (possibly, subject to compiler fiat) separate NSStrings with the same value.

The actual value for UIApplicationDidEnterBackgroundNotification is contained within UIKit, so when the UIKit library is loaded the pointer will be filled in. The problem is that iOS 3.2 doesn't define UIApplicationDidEnterBackgroundNotification, so what you end up with is an undefined pointer. Hence you pass an undefined pointer to the NSNotificationCenter, causing the crash when it attempts to read it.

The smart thing to do is probably:

UIDevice *currentDevice = [UIDevice currentDevice];

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

So you check whether the version of the UIDevice class on this device knows that multitasking is even a possibility and if so whether multitasking is supported. The standard C shortcut evaluation means the thing after the && will be evaluated only if the thing before it succeeds, so there's no chance of accidentally issuing an unrecognised method call.

Only if multitasking is supported do you register for the notification. This will be safe because the UIApplicationDidEnterBackgroundNotification string was introduced at the same time as multitasking. There is no device that supports multitasking and doesn't provide the string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM