在使用 MagicalRecord CocoaPod 初始化 +initialize 时,Objective-C 无法识别的选择器

Posted

技术标签:

【中文标题】在使用 MagicalRecord CocoaPod 初始化 +initialize 时,Objective-C 无法识别的选择器【英文标题】:Objective-C unrecognized selector on +initialize with the MagicalRecord CocoaPod 【发布时间】:2013-01-31 19:08:48 【问题描述】:

注意:请参阅问题底部的更新,我已经设法在调试方面更进一步。

我认为这是我的项目设置的一个问题,但我不确定要查看什么,因为没有编译错误。

我在项目中包含了 MagicalRecord 2.1(当前稳定),并由 CocoaPods 管理它。我没有更改 CocoaPods 的任何构建设置,它完美地管理了我的其他依赖项,到目前为止我还没有遇到任何问题。

我已将#import <MagicalRecord/CoreData+MagicalRecord.h> 添加到我的App-Prefix.pch 文件中,Xcode 为我提供了正确设置所期望的所有符号建议。我没有收到任何编译器错误,所以我只能假设 CocoaPods 已成功将 MR 构建到库中,并且我已成功将其导入到我的代码中。

当我在我的应用程序委托中初始化 MagicalRecord 时出现问题:

- (void)applicationDidFinishLaunching:(NSNotification *)notification 
  [MagicalRecord setupCoreDataStack];

  //... other code

初始化几乎是要运行的第一个代码,并且没有其他任何已运行的代码会与此冲突。

该行挂起,执行该行后没有任何内容。我设法找到了挂起发生的位置。将消息传递给MagicalRecord 会导致类调用+initialize,这不起作用。更具体地说,在初始化方法中调用的self 上的任何方法都会导致引发unrecognized selector 异常。

据我所知,这有两个奇怪的地方:

    为什么找不到方法实现? 为什么会导致它挂起?

我对Objective-C如何使用initialize方法了解的不够多,是不是在抛出异常时会挂起?

这是异常发生时的堆栈跟踪:

frame #0: 0x00007fff93a2e3c5 libobjc.A.dylib`objc_exception_throw
frame #1: 0x00007fff996dc31a CoreFoundation`+[NSObject(NSObject) doesNotRecognizeSelector:] + 186
frame #2: 0x00007fff996341ee CoreFoundation`___forwarding___ + 414
frame #3: 0x00007fff99633fd8 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #4: 0x000000010004e32c River`+[MagicalRecord initialize] + 92 at MagicalRecord.m:89
frame #5: 0x00007fff93a25236 libobjc.A.dylib`_class_initialize + 310
frame #6: 0x00007fff93a250f3 libobjc.A.dylib`prepareForMethodLookup + 164
frame #7: 0x00007fff93a24eef libobjc.A.dylib`lookUpMethod + 71
frame #8: 0x00007fff93a232fc libobjc.A.dylib`objc_msgSend + 188
frame #9: 0x0000000100001d36 MyApp`-[AppDelegate applicationDidFinishLaunching:] + 86 at AppDelegate.m:46

非常感谢您对此的任何帮助,包括我可以尝试进一步调试的技巧。

更新:

删除我的 Derived Data 目录后,程序无法链接到 Pod。我相信 Xcode 在我添加 MagicalRecord 并链接到它的旧版本后未能构建 Pod(这可能是错误的,我不确定)。

这似乎是 Xcode 和/或 CocoaPods 问题。我正在尝试弄清楚如何让它正确构建 Pod,但我不是 CocoaPods 或 Xcode 构建设置方面的专家,所以我不确定我能走多远。

更新 2:

Xcode 和项目设置存在问题,它与旧的 Pod 库链接,并且仅在删除派生数据后才引起问题。现在我回到了第 1 点,遇到了无法识别的选择器问题。

【问题讨论】:

看起来像是你正在调用的东西或 MagicalRecord 本身的问题。 这是我的想法,但是看到没有其他人报告过这个问题,我怀疑这是我的项目设置的问题。但我对 Objective-C 内部的了解不够多,不知道为什么它无法找到方法。 【参考方案1】:

解决方案是在使用 Pod 库的产品设置中的 Other Linker Flags 设置中使用 -all_load 链接器标志。

当您链接到 pod 库时,除非您这样做,否则 clang 会删除未使用的符号,并且由于您的应用程序不会在任何地方调用 +swizzleShorthandMethods,它会被删除。

【讨论】:

这已经足够接近,所以标记为答案。实际问题是主项目本身没有使用 -all_load 和 -ObjC,而不是 Pods 项目。 添加-all_load 标志会产生duplicate symbol _OBJC_CLASS_$_AFImageCache 错误。【参考方案2】:

对不起,我从来没有解决过这个问题,而且看起来没人知道它为什么不起作用。我尝试与 Magical Record 的开发人员一起解决,但最终的答案是不使用 CocoaPods 并手动添加代码。我希望我能对此给出更好的解决方案,但我没有时间花几天时间调试这个问题,而且我认为我对 CocoaPods、Xcode 编译过程和 Objective-C 运行时了解不够调试它。

【讨论】:

【参考方案3】:

我手动添加了MagicalRecord 库,遇到了这个错误。我的问题出在 .pch 文件中,因为 MagicalRecord/CoreData+MagicalRecord.h 的导入高于定义:#define MR_SHORTHAND

将定义放在上面的导入解决了我的问题。

【讨论】:

【参考方案4】:

在您的 Podfile 中更新 MagicalRecord 参考如下:

pod 'MagicalRecord/Shorthand', '~> 2.2'

它将在您的Pods/Pods-MagicalRecord-prefix.pch 文件中包含#define MR_SHORTHAND

【讨论】:

以上是关于在使用 MagicalRecord CocoaPod 初始化 +initialize 时,Objective-C 无法识别的选择器的主要内容,如果未能解决你的问题,请参考以下文章

在 TodayExtension 中使用 MagicalRecord (CoreData)

Swift 3 - MagicalRecord:如何在空实体上使用 findFirst

使用 MagicalRecord 在后台执行获取请求

MagicalRecord 如何在关系中添加对象

使用 MagicalRecord 在核心数据中映射和发布实体

如何将 groupBy 与 MagicalRecord 一起使用?