【发布时间】:2018-04-02 02:53:34
【问题描述】:
我发现了很多关于 NSArray element failed to match the Swift Array Element type 错误的帖子。但是,我仍然无法让它工作。 我怀疑该问题与我制作的目标 C 框架绑定有关,而不是强制转换问题。其中,我不明白的一件事是为什么代码在 lldb p 指令中工作,而不是作为在主机 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 行将不起作用。我发现的相关问题都没有回答这个问题。我承认我是一个 swift/objc 新手,如果不是与 objc-swift 框架映射过程相关的问题,可能有一些我不明白的明显问题。
getMuses 函数由 djinni 包装,使用我编写的模块映射将专有目标 C 框架绑定到 swift。这是我写的模块图。我对其他函数绑定没有任何问题(参见 cmets)。删除 [system] 属性不会触发任何额外的警告。
module Muse [system] {
header "Muse.framework/Headers/Muse.h"
export *
}
djinni 生成的声明:
public func getMuses() -> [IXNMuse]
原始的objc声明:
- (nonnull NSArray<IXNMuse *> *)getMuses;
定义不可用,因为框架是专有的。
返回的指针不太可能为 null 或指出错误的内存地址,因为 lldb 对屏幕截图中显示的 getName 方法的调用不会给出正确的结果。
【问题讨论】:
-
我假设您不能将 IXNMuse 转换为 _。尝试使用 let object = muses.first 作为? IXNMuse
-
不幸的是,这不起作用,我得到了同样的错误。
-
另外,快速帮助(alt + 点击
first)识别类型IXNMuse(它在声明中声明var first: IXNMuse? { get }) -
我必须为 muse 库编写模块映射(从目标 c 框架包装)。我的目标是一个快速的框架。我想知道这个问题是否相关,因为我在类似的非框架代码中没有这个问题,但我不得不承认我是两种语言的完全新手,所以这也可能完全不相关。
-
感谢您添加声明。但没有包含任何信息,我可以找到一些线索来解决您的问题。如果将
print(type(of: (muses as NSArray).firstObject!))放在导致崩溃的行之前,您会得到什么?
标签: objective-c swift frameworks lldb djinni