休息套件Cocoapods:映射操作失败/未找到任何可映射值 [英] RestKit & Cocoapods: Mapping operation failed / did not find any mappable values

查看:114
本文介绍了休息套件Cocoapods:映射操作失败/未找到任何可映射值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 RKMappingTest s执行RestKit映射代码的单元测试时,它们会失败,并出现以下异常:

When executing unit tests for RestKit Mapping Code with RKMappingTests, they fail with exceptions such as:

映射操作失败:给定零个目标对象,并且无法实例化要映射的目标对象。

或(将目标对象传递到 RKMappingTest ):

or (when a destination object is passed into the RKMappingTest):

映射操作未找到给定对象表示形式中属性和关系映射的任何可映射值

RestKit是通过Cocoapods使用以下Podfile安装的:

RestKit is installed through Cocoapods using the following Podfile:

target :MyTarget do
    pod 'RestKit'
end

target :MyTargetTests do
    pod 'RestKit/Testing'
    pod 'RestKit/Search'
end




已创建要测试的RKMapping在常规应用程序捆绑包中,并在使用lldb调试器的 po 命令时正确显示。

当生成RKEntityMapping的方法被复制粘贴到单元测试类中并在那里执行,一切正常。

When the method for generating the RKEntityMapping is copy-pasted into the unit test class and executed there, everything is working properly.

尽管我确实回答了我自己的问题,希望对其他有相同问题的人有用,但我鼓励任何能提出更好解决方案的人来张贴它。

Though I did answer my own question in the hope that it would be useful for somebody else with the same problem, I encourage anybody who can come up with a better solution to post it.

推荐答案

原因为何:



免责声明:

我不是静态库,链接和相关依赖项方面的专家。如果我对链接或Cocoapods的工作方式有疑问,请纠正我。

对此 Podfile ,Cocoapods构建了两个静态库-每个目标库一个。

For this Podfile, Cocoapods builds two static libraries – one for each target.

编译项目时,中的所有代码MyTarget 将链接到 LibPods-MyTarget.a 库和 MyTargetTests 将链接到 LibPods-MyTargetTests.a 库。

它们都包含 RestKit /的副本。 ObjectMapping 组件(因为它是 RestKit RestKit / Testing 的依赖项)。

When the project is compiled, all the code in MyTarget will get linked against the LibPods-MyTarget.a library and all the code in MyTargetTests will get linked against the LibPods-MyTargetTests.a library.
Both of them contain a copy of the RestKit/ObjectMapping component (since it is a dependency of both RestKit and RestKit/Testing).

在应用程序源(MyTarget)中生成 RKMapping 时,该类实现来自 LibPods-MyTarget。

在单元测试类中使用该映射时,RestKit实现是从另一个库链接的。

When generating a RKMapping in the application source (MyTarget), the class implementation from LibPods-MyTarget.a is used.
When using that mapping inside the unit test class, the RestKit implementation is linked from the other library.

从理论上讲,两者都实现ntations包含相同的源代码,两个类具有相同的名称,相同的类号,甚至底层的 objc_class 结构都包含相同的内容。

Theoretically, both implementations contain the same source code, both classes have the same name, the same class number and probably even the underlying objc_class structs contain the same content.

当您从测试类中调用方法时,它将按应有的方式执行(实现来自应用程序库)。
说:根据对象在alloc初始化的位置,将从不同副本在不同内存位置加载相等的源代码。

When you call a method on it from the test class, it will execute as it should (with implementation coming from the apps library). Saying: depending on where the object was alloc-inited, equal source code will be loaded from a different copy at a different memory location.

但是,从Objective-C开始 Class 构造的层次高于基础 objc_class 构造的层次,但两者并不相同。

However, since the Objective-C Class construct is higher level than the underlying objc_class struct, they are not both the same.

示例含义:

让我们假设我们有一个名为 MyObject ,其中包括带有以下签名的方法:

Let's assume we have have a class called MyObject, that includes a method with the following signature:

+ (RKObjectMapping*)generateMapping;

虽然方法本身运行良好,但此测试将失败:

While the method itself works perfectly fine, this test would fail:

- (void)testClassEquality {
    RKEntityMapping *mappingFromAppBundle = [MyObject generateMapping];
    Class testBundleMappingClass = [RKMapping class];
    
    XCTAssert([mappingFromAppBundle isMemberOfClass:testBundleMappingClass],
              @"Mapping class from app bundle doesn't match Mapping class from test bundle");
}

因为:

[ RKMapping类] 来自 LibPods-MyTarget.a

!=

[RKMapping类] 来自 LibPods-MyTargetTests.a

RestKit在很大程度上依靠 isMemberOfClass: isSubclassOf:操作来实现其功能。因此,这种重复的实现会破坏它。

RestKit heavily relies on isMemberOfClass: and isSubclassOf: operations for implementing its functionality. Therefore this kind of duplicate implementation breaks it.

不要对两个目标使用两种不同的Cocoapod配置。使用简单的Podfile,例如:

Don't use two different Cocoapod configurations for the two targets. Use a simple Podfile such as:

pod 'RestKit'    
pod 'RestKit/Testing'
pod 'RestKit/Search'

然后对两个目标使用相同的库/配置。链接程序针对两个目标针对同一副本进行链接。

Then use the same library/configuration for both targets. The linker link against the same copy for both targets.

死代码剥离会阻止不必要的代码包含在最终应用程序中。

Dead-code-stripping should prevent the unneeded code from being included in your final application.

但是:如果您具有 -ObjC -all_load 链接器,仍需要在每个版本上对其进行编译标记设置后,未使用的代码将随您的应用一起提供。

However: It will still need to be compiled on each build and if you have the -ObjC or -all_load linker flags set, the unused code will be shipping with your app.


我强烈建议您不要这样做,因为它几乎破坏了单元测试的目的。我将其视为另一种解决方法,并为了完成而将其包括在内:

I strongly advise against this, since it pretty much defeats the purpose of a unit test. I've seen this as another workaround and included it for the sake of completion:

将代码的实现复制并粘贴到单元测试类中,然后

Copy and paste the implementation of the code into the unit test class and use it from there.

Cocoapods首先为每个组件创建一个静态库,然后将其合并为每个目标的更大库,项目或工作区。

Cocoapods makes a static library for every single component first and combines them into a bigger library for each target, project or workspace.

应该可以将小型库直接链接到目标中,而无需使用大型联合。这样,在没有自动化的情况下,一个人就会杀死Cocoapods所建立的自动依赖管理。

It should be possible, to link the small libraries directly into the target without using the big union. By doing this, without automation, one would however kill the automatic dependency management, that Cocoapods was built for.

如果有人有空并为之实现脚本或修改Cocoapods要添加功能,请让我知道。

If anybody has some time on their hands and implements a script for this or modifies Cocoapods to add functionality, please let me know.

如果我缺少可以Cocoapods已经拥有或您知道任何其他解决方案,请发表评论或将其作为其他答案。

If I'm missing a functionality that Cocoapods already has or you know any additional solutions, please comment or post it as another answer.

这篇关于休息套件Cocoapods:映射操作失败/未找到任何可映射值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆