为啥检查 [NSMetadataQuery 类] 在 iOS 4.2.1 上崩溃?

Posted

技术标签:

【中文标题】为啥检查 [NSMetadataQuery 类] 在 iOS 4.2.1 上崩溃?【英文标题】:Why is checking [NSMetadataQuery class] crashing on iOS 4.2.1?为什么检查 [NSMetadataQuery 类] 在 iOS 4.2.1 上崩溃? 【发布时间】:2012-05-30 06:58:48 【问题描述】:

我正在尝试使用this approach, described by Marco Arment, for checking if a class exists before using it。使用正确的设置,类会在适当的时候自动弱链接。正如 Marco 所描述的,“您可以安全地继承子类或拥有指向您想要的任何东西的指针(只要您注意不要在它们不可用时实例化它们)”。

我的应用在 ios 5 上运行良好。我遵循了链接中提到的条件:

基础 SDK 是最新的 iOS (iOS 5.1) 部署目标是 iOS 4.0 C/C++/Objective-C 的编译器是 Apple LLVM 编译器 3.1(也尝试过 LLVM GCC 4.2)

每当我引用 NSMetadataQuery 时,我都会先确保该类存在:

if ([NSMetadataQuery class] != nil) …

尽管如此,如果我尝试在装有 iOS 4.2.1 的 iPod touch 上运行我的应用程序,它会在启动时立即崩溃:

dyld: Symbol not found: _OBJC_CLASS_$_NSMetadataQuery

我已经尝试注释掉我的应用程序运行正常的所有代码。一旦我添加回对 NSMetadataQuery 的单个引用,它就会崩溃。我什至试过这个:

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

仅包含该行,并且没有对 NSMetadataQuery 的其他引用,会使应用程序崩溃。更奇怪的是,检查其他 iOS 5 类并不会导致任何问题:

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

效果很好,正如预期的那样。

我已经能够使用更丑的 NSClassFromString() 解决该问题以确保该类存在,但我很想知道为什么其他方法不起作用。

【问题讨论】:

【参考方案1】:

我对此没有任何解释,但我遇到了和你一样的问题。无论我/你做什么,NSMetadataQuery 都不会被弱链接...

参考这个答案,确实是另一个问题中最好的:

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

简而言之,其他自动弱链接似乎有效,只是您必须从源代码中删除 NSMetadataQuery* 并替换为 id。使用NSClassFromString() 等实例化该类。但是,像UIDocument 这样的其他类没有问题,因此您可以安全地以正常的无汗方式使用它们。

【讨论】:

【参考方案2】:

NSMetadataQuery 在 iOS 5.0 及更高版本中可用,因此任何低于该版本的版本都不知道它是什么。只需在代码中使用它,类名就会被添加到符号表中,并在应用启动时进行查找。

【讨论】:

正如in the article I linked to 解释的那样,iOS 4.2 SDK 及更高版本中有一个功能可以自动弱链接需要它的类。我还举了一个例子来说明这个功能在哪里可以正常工作——UIDictationPhrase 类只在 iOS 5.1 和更高版本中可用。

以上是关于为啥检查 [NSMetadataQuery 类] 在 iOS 4.2.1 上崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

NSMetadataQuery 忽略自定义文件包类型

NSMetadataQuery数据库

UIDocument openWithCompletionHandler:强制 NSMetadataQuery 更新

如何限制从 NSMetadataQuery 返回的结果数量?

使用 NSMetadataQuery 在目录中搜索文件

NSMetadataQuery 返回显然不存在的文件