Swift 框架 returns 'ambiguous use of' lldb 中的方法扩展

Swift Framework returns 'ambiguous use of' method extension in lldb

我已经升级到 Xcode 11 & swift 5,并且在通过框架提供方法扩展时遇到了一个问题。更具体地说,在一个结构如下的项目中:

-> Main Project
-> Framework created from sources in 'Main Project'
-> Subproject using the above Framework (Sources packaged in the framework are not visible to the sub-project)

一切都编译并且 运行 很好,但是当 运行 在子项目上调试会话时, 'Framework' return error: ambiguous use of 中的所有扩展被调用时从 lldb 命令行。这是一个提供想法的代码示例:

创建一个 macOs 命令行项目,并添加一个新目标,'MagicFramework',并在一个文件中 Spells.swift(确保该文件对 Main & MagicFramework 可见)

import Foundation

extension String {
    public func castSpell() -> String {
        return "✨ " + self
    }
}

然后创建一个子项目'Wizard',并在一个文件wizard.swift中(只对向导可见):

import Foundation
import MagicFramework


public class Tadaa {

    public func magic(spell:String) -> String {
        return spell.castSpell()
    }
}

在向导的 main.swift 文件中,添加:

import Foundation

let aa = Tadaa().magic(spell: "this is magic")

print(aa)

你应该有以下结构:

-> Main project
----> MagicFramework
----> Wizard subproject

然后构建&运行 'Wizard' 子,在Tadaa 中的spell.castSpell() 上有一个断点。在 lldb 提示符下,键入:

(lldb)po spell.castSpell()
error: <EXPR>:3:1: error: ambiguous use of 'castSpell()'
spell.castSpell()

为什么?? Xcode 10.

没有出现这个问题

依我拙见,这只能是一个错误。

如果我设置你在问题中给出的例子,我可以重现问题。

在断点处,我得到

(lldb) po spell.castSpell()
error: <EXPR>:3:1: error: ambiguous use of 'castSpell()'
spell.castSpell()
^

正如你描述的那样。

但是,如果我在 lldb 中查找函数 castSpell,我得到:

(lldb) image lookup -vn castSpell
1 match found in /Users/lameyl01/Library/Developer/Xcode/DerivedData/Main-dsjbnoyousgzmrdnqxtxoeyeyzpv/Build/Products/Debug/MagicFramework.framework/Versions/A/MagicFramework:
        Address: MagicFramework[0x0000000000000ab0] (MagicFramework.__TEXT.__text + 0)
        Summary: MagicFramework`(extension in MagicFramework):Swift.String.castSpell() -> Swift.String at Spells.swift:12
         Module: file = "/Users/lameyl01/Library/Developer/Xcode/DerivedData/Main-dsjbnoyousgzmrdnqxtxoeyeyzpv/Build/Products/Debug/MagicFramework.framework/Versions/A/MagicFramework", arch = "x86_64"
    CompileUnit: id = {0x00000000}, file = "/Users/lameyl01/tmp/Main/MagicFramework/Spells.swift", language = "swift"
       Function: id = {0x100000038}, name = "(extension in MagicFramework):Swift.String.castSpell() -> Swift.String", mangled = "$sSS14MagicFrameworkE9castSpellSSyF", range = [0x000000010033fab0-0x000000010033fb21)
       FuncType: id = {0x100000038}, byte-size = 8, decl = Spells.swift:12, compiler_type = "() -> ()"
         Blocks: id = {0x100000038}, range = [0x10033fab0-0x10033fb21)
      LineEntry: [0x000000010033fab0-0x000000010033fabf): /Users/lameyl01/tmp/Main/MagicFramework/Spells.swift:12
         Symbol: id = {0x00000005}, range = [0x000000010033fab0-0x000000010033fb21), name="(extension in MagicFramework):Swift.String.castSpell() -> Swift.String", mangled="$sSS14MagicFrameworkE9castSpellSSyF"
       Variable: id = {0x100000055}, name = "self", type = "Swift.String", location = DW_OP_fbreg(-16), decl = Spells.swift:12

这意味着 lldb 找到了一个匹配项:MagicFramework 库中的扩展。所以没有理由这应该是模棱两可的。

为了完整起见,我还检查了变量 spell 的类型,正如 llbd 所见:

(lldb) frame variable spell
(String) spell = "this is magic"

总结一下: lldb 知道 类型是字符串。它 知道 在扩展中定义了一个函数 castSpell 并且它知道该函数的一个实现。但它仍然显示错误消息。

所以除非我在这里遗漏了一些重要的东西,否则这一定是一个 lldb 错误。

我的扩展程序也有同样的问题。在我的情况下,这是我在调试时经常使用的单个函数,所以我刚刚创建了一个全局函数,在您的情况下,它只接受字符串并在内部调用该扩展。与@aepryus 在第一个答案的评论中指出的非常相似。

import Foundation

extension String {
    public func castSpell() -> String {
        return "✨ " + self
    }
}

func castSpell(_ string: String) -> String {
    return string.castSpell()
}

然后像这样使用它:

(lldb) po castSpell("this is magic")
"✨ this is magic"

(lldb)