I've got an iPhone app that's mainly targetting 3.0, but which takes advantage of newer APIs when they're available. Code goes something like this:
if (UIApplicationDidEnterBackgroundNotification != NULL) {
[nc
addObserver: self
selector: @selector(irrelevantCallbackName:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
}
Now, according to everything Apple's ever said, if the relevant APIs are weakly linked, that will work fine because the dynamic linker will evaluate UIApplicationDidEnterBackgroundNotification
to NULL
. Except that it doesn't. The application compiles, but as soon as it hits if (UIApplicationDidEnterBackgroundNotification != NULL)
it crashes with EXC_BAD_ACCESS
.
Is this simply a matter of a compiler flag I need to set? Or am I going about this the wrong way?
Aaand I figured it out. For symbols that are not functions (extern const int foobar
, for instance), you have to compare against the address of the symbol, not the symbol itself, so:
if (&UIApplicationWillEnterForegroundNotification != NULL)
etc;
Which in retrospect is kind of obvious, but I still fault the entire universe around me for not ever mentioning the distinction.
Here is what I had to do when checking for an external framework constant.
const CLLocationAccuracy * ptr = &kCLLocationAccuracyBestForNavigation;
BOOL frameworkSupports = (ptr != NULL);
if (frameworkSupports) {
return kCLLocationAccuracyBestForNavigation;
} else {
return kCLLocationAccuracyBest;
}
It would not work without the ptr variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With