Why is checking [NSMetadataQuery class] crashing on iOS 4.2.1?

308 views Asked by At

I'm attempting to use this approach, described by Marco Arment, for checking if a class exists before using it. With the correct settings, classes are automatically weak-linked when it's appropriate. As Marco describes, "you can safely subclass or have pointers to whatever you want (as long as you’re careful not to instantiate them when they’re not available)".

My app runs fine on iOS 5. I've followed the conditions mentioned at the link:

  • Base SDK is Latest iOS (iOS 5.1)
  • Deployment Target is iOS 4.0
  • Compiler for C/C++/Objective-C is Apple LLVM compiler 3.1 (also tried LLVM GCC 4.2)

Any time I reference NSMetadataQuery I'm making sure the class exists first:

if ([NSMetadataQuery class] != nil) …

Despite all this my app crashes immediately on launch if I try to run it on an iPod touch with iOS 4.2.1:

dyld: Symbol not found: _OBJC_CLASS_$_NSMetadataQuery

I've tried commenting out all the code any my app runs fine. As soon as I add back in a single reference to NSMetadataQuery, it crashes. I've even tried this:

if ([NSMetadataQuery class] != nil) NSLog(@"OK");

Simply including that line, and no other reference to NSMetadataQuery, crashes the app. Even more strange, checking for other iOS 5 classes doesn't cause any problems:

if ([UIDictationPhrase class] != nil) NSLog(@"OK");

That works fine, as expected.

I have been able to work around the problem using the uglier NSClassFromString() to make sure the class exists, but I'd love to know why the other approach isn't working.

2

There are 2 answers

0
Jonny On BEST ANSWER

I don't have an explanation to this but I ran into the same problem as you. No matter what I/you do, NSMetadataQuery just won't be weak linked...

Refer to this answer, which is really the best one in another question:

https://stackoverflow.com/a/8426591/129202

In short, other auto weak linking seems to work, it's just NSMetadataQuery* that you have to remove from source and replace with id. Instantiate the class with NSClassFromString() etc. No hiccups on other classes like UIDocument however so you can safely use those in the normal sweat free way.

1
Oscar Broman On

NSMetadataQuery is available in iOS 5.0 and above, so any versions below that has no clue as to what it is. By merely using it in your code, the class name will be added to a symbol table and looked-up when the app launches.