16

作为测试,我创建了两个框架。两个框架都包含这个扩展:

public extension UIDevice {
    var extraInfo: UIDeviceExtraInfo {
        return UIDeviceExtraInfo()
    }
}

public class UIDeviceExtraInfo {
    public var prop: String = "Device1"  //"Device2" is used in another framework
}

然后我导入了这两个框架并尝试打印UIDevice.currentDevice().extraInfo.prop. Swift 编译器给出错误:Ambiguous use of extraInfo".

如何解决这样的名称冲突?

4

3 回答 3

6

在这种特定情况下,您可以extraInfo通过明确指定预期类型来消除 prop 的歧义:

import FW1
import FW2

let fw1Info = UIDevice.currentDevice().extraInfo as FW1.UIDeviceExtraInfo
let fw2Info = UIDevice.currentDevice().extraInfo as FW2.UIDeviceExtraInfo
print(fw1Info.prop) // -> Device1
print(fw2Info.prop) // -> Device2

但是,当方法/道具返回相同的类型时:

// FW1
public extension UIDevice {
    var myInfo: String { return "Device1" }
}

// FW2
public extension UIDevice {
    var myInfo: String { return "Device2" }
}

// App
import FW1

print(UIDevice.currentDevice().myInfo) // -> ???

没有办法消除它们的歧义。并且无论应用程序代码导入哪个框架,看起来,实际调用的实现取决于“先到先得”方式的链接框架和库中的顺序。但是,据我所知,不能保证这种行为。

截屏

于 2015-11-24T13:18:39.947 回答
1

在做了一些实验之后,我发现的唯一方法是将其中一个框架导入到您的源文件中。

于 2015-11-24T13:14:25.177 回答
0

在我拥有 CryptoSwift 的项目中发现了这个,之后我已经“编译”了一个没有源代码的专有框架,只有头文件。

因此,此时您有 3 个选项:

  1. 要求提供者更改姓名
  2. 修改其中一个(在这种情况下,crypto swift,因为它是开源的,您可以修改扩展名,显然不仅在调用它的代码中,而且在克隆的依赖项中......如果您需要,这很麻烦升级依赖项)
  3. 更改您调用它的名称,以便没有错误并知道您要使用的内部,我确实在 Data 的这种情况下进行了扩展,并将 CryptoSwift 所做的复制到我自己存在冲突的文件中(所以它需要一个本地定义代码):
extension Data {
    public var myBytes: Array<UInt8> {
        return Array(self)
    }
}

看到现在我必须将我的代码的所有调用更改为 myBytes 并且我有实现这个调用的源代码,所以即使你不能做 1 或 2 也不会再发生冲突(因为很麻烦)。如果你不能做3个中的任何一个,我想没有解决方案。

顺便说一句,不幸的是 swift 不支持在语言本身上消除歧义的方法。

于 2020-02-24T19:50:11.823 回答