1

我发现了很多关于该NSArray element failed to match the Swift Array Element type错误的帖子。但是,我仍然无法让它工作。我怀疑这个问题与我所做的目标 C 框架绑定有关,而不是铸造问题。除其他外,我不明白的一件事是为什么代码在 lldbp指令中工作,而不是作为在主机 ios 应用程序中执行的单元测试(否则我无法测试它,因为代码需要 B-LE 无法从iphone模拟器)。

class onceFirstMuseConnected: IXNMuseListener {
    let museManager: IXNMuseManager
    let callback: (_ muse: IXNMuse) -> Void

    init(museManager: IXNMuseManager, callback: @escaping (_ muse: IXNMuse) -> Void) {
        self.museManager = museManager
        self.callback = callback
        museManager.setMuseListener(self)
        museManager.startListening()
    }

    func museListChanged() {
        let muses: [IXNMuse] = museManager.getMuses()
        guard muses.count > 0 else {
            return
        }
        let _ = muses.first!.getName() // <<<< `muses.first` fails as well as any other
                                       //      kind of array's item access with "Fatal
                                       //      error: NSArray element failed to match the
                                       //      Swift Array Element type"
    }
}

奇怪的是我能够使该行在 lldb 中工作,如下图所示。

lldb 工作

编辑:由于我有多次反对票,我希望能解释一下为什么 lldb 行在主执行崩溃时在评论中起作用。如果是类型转换问题,我认为 lldb 行将不起作用。我发现的相关问题都没有回答这个问题。我承认我是一个 swift/objc 新手,如果这不是与 objc-swift 框架映射过程相关的问题,可能有一些我不明白的事情。

getMuses函数由 djinni 使用我编写的模块映射包装,用于将专有的目标 C 框架绑定到 swift。这是我写的模块图。我对其他函数绑定没有任何问题(见评论)。删除该[system]属性不会触发任何其他警告。

module Muse [system] {
    header "Muse.framework/Headers/Muse.h"
    export *
}

djinni 生成的声明:

public func getMuses() -> [IXNMuse]

原始的 objc 声明:

 - (nonnull NSArray<IXNMuse *> *)getMuses;

该定义不可用,因为该框架是专有的。

返回的指针不太可能为 null 或指出错误的内存地址,因为 lldb 对屏幕截图中显示的 getName 方法的调用不会给出正确的结果。

4

1 回答 1

1

编辑后的答案

Muse.framework是一个静态框架。XCTests 内置在宿主应用程序中嵌入的包中。在我的设置中,涉及 3 个目标:我开发的框架、用于测试的主机应用程序和 XCTest 包。

静态框架嵌入在目标二进制文件中使用的符号。

为避免重复符号问题,静态框架应仅链接到目标框架**,而不是 xctest 包或测试主机应用程序,它们通过链接目标框架来过渡链接符号。

为了确保目标框架嵌入其静态链接框架依赖项的所有符号,必须将 -force_load 标志后跟静态依赖项路径添加到目标框架链接选项 (OTHER_LDFLAGS)

原始答案

积分转到OOPer在问题的评论中寻求帮助。

由于我不明白的原因,我得到了 IXNMuse 类的双重定义。两个定义之间的 Swift 冲突是NSArray element failed to match the Swift Array Element type我遇到错误的原因。

修复程序

当我执行以下过程时,问题消失了:

A.在测试以下代码时

let muses: NSArray = museManager.getMuses() as NSArray
let muse: IXNMuse = muses.firstObject! as! IXNMuse

我在运行时收到

Could not cast value of type 'IXNMuse' (0x103cfa180) to 'IXNMuse' (0x103e965e0).

B.我有两条import Muse语句,一条在我的测试文件中,一条在我的框架目标源文件中。从测试文件中删除import Muse语句(使用相关代码)。这通过删除双重 IXNMuse 定义让测试通过。

C.Muse.frameworkLink Binary with Libraries我的测试目标中删除了,因为它已经包含在我测试的框架目标中。import Muse我从刚刚删除的测试文件中放回了语句(使用相关代码,因为我仍然需要它)。即使在两个目标源文件中使用双重 Muse 导入,测试仍然通过。

D.我放回了我的测试目标的Muse.framework后面Link Binary with Libraries(我相信让两个目标链接具有三角依赖的同一个框架并不是一个错误)。因此,我回到了与我最初写问题时的状态相似的状态。该问题没有再次出现,测试仍然通过。

结论

我仍然有点困惑,为什么我一开始会遇到这个问题。我可能并不完全处于与我相同的状态,并且在更改我不记得的链接配置的过程中做了一些事情。

于 2018-04-02T20:56:40.487 回答