更新 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
),现在,在上面的示例中,mgr
是 nil
。如果我在上面的第二行放一个断点,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 <RestKit.h>
变成了#import <RestKit/RestKit.h>
【讨论】:
以上是关于更新 Cocoapods gem 后,测试中的类似乎是从不同的 NSBundle 加载的,导致零单例的主要内容,如果未能解决你的问题,请参考以下文章