更新 Cocoapods gem 后,测试中的类似乎是从不同的 NSBundle 加载的,导致零单例

Posted

技术标签:

【中文标题】更新 Cocoapods gem 后,测试中的类似乎是从不同的 NSBundle 加载的,导致零单例【英文标题】:Class appears to be loaded from different NSBundle in tests after updating Cocoapods gem, resulting in nil singleton 【发布时间】:2015-08-26 21:22:21 【问题描述】:

我在我的应用程序中使用 RestKit,并在 AppDelegate 中进行设置。我有一些依赖于RKObjectManager 单例的单元测试。这是在 AppDelegate 中设置的。一些测试专门为测试设置了托管对象存储,如下所示。其他人直接调用getObject等来测试响应映射。

这是在我的测试中setUp

RKObjectManager *mgr = [RKObjectManager sharedManager];
[mgr setManagedObjectStore:managedObjectStore];

这已经成功运行了很长时间。

我最近将我的 Cocoapods gem 从 0.33.1 更新到最新版本(现在是 0.38.2),现在,在上面的示例中,mgrnil。如果我在上面的第二行放一个断点,sharedManager 显然返回一个非零值,但我的局部变量是零:

(lldb) po mgr
 nil
(lldb) po [RKObjectManager sharedManager]
<RKObjectManager: 0x7fe9e2d1d5e0>

我怀疑我实际上在运行时加载了两个 RKObjectManager 副本(一个来自应用程序包,一个来自测试包)。我有tried all the solutions listed here,但感兴趣的评论talks about how each target gets its own copy of the class。事实上,如果我在RKObjectManager 上覆盖+(void) load 方法,它会被调用两次。

如果我将共享管理器的引用作为属性存储在我的 AppDelegate 上,那么我可以成功地从中检索共享实例 - 只是不能从上面的类方法中检索。我不想在我的所有测试中重复这种变通方法。

如何配置 Cocoapods 以将 RKObjectManager 的“正确”版本与我的测试链接,以便我可以再次直接检索共享实例?

我的播客文件:

platform :ios, '8.0'

target 'Closeout' do
    pod 'RestKit'
    ... some other pods
end

target 'CloseoutTests' do
    pod 'RestKit/Testing'
    pod 'OHHTTPStubs'
end

编辑:我有一个解决方法肯定比仅仅为了测试的利益而在 AppDelegate 上公开一个属性更好,但我仍然想知道如何避免这样做:

AppDelegate* delegate = (AppDelegate*)([UIApplication sharedApplication].delegate);
NSBundle *appBundle = [NSBundle bundleForClass:[delegate class]];
id objMgr = [appBundle classNamed:@"RKObjectManager"];
[[objMgr sharedManager] setManagedObjectStore:managedObjectStore];

【问题讨论】:

【参考方案1】:

CocoaPods 在 0.36 版 - the release blog has a very good explanation of why this is necessary 中更改了添加依赖项的方式,但总体思路是它是 Swift 支持所必需的。

我将 CocoaPods 0.36 中引入的以下关键字添加到我的 Podfile 中:

use_frameworks!

我删除了我的目标并改用link_with,所以我的 Podfile 看起来像这样:

platform :ios, '8.0'

link_with 'Closeout', 'CloseoutTests'
use_frameworks!

pod 'RestKit'
pod 'RestKit/Testing'
pod 'OHHTTPStubs'
... other pods

此外,我必须确保我运行的是 RestKit 0.25 或更高版本,如 includes this PR,启用对框架的支持。

pod 'RestKit', '0.25.0'

最后,我不得不修复一堆编译错误:

#import &lt;RestKit.h&gt; 变成了#import &lt;RestKit/RestKit.h&gt;

【讨论】:

以上是关于更新 Cocoapods gem 后,测试中的类似乎是从不同的 NSBundle 加载的,导致零单例的主要内容,如果未能解决你的问题,请参考以下文章

cocoapods无法使用淘宝镜像,使用https://gems.ruby-china.org/方法

更新Xocde 9 后, Cocoapods异常记录

更新 cocoapods 出现如下错误:

cocoapods升级

安装 cocoapods 时出现 gem 本机扩展错误

无法将 cocoapods 从 1.0.0 升级到 1.0.1