命名来自不同框架的扩展方法的冲突

时间:2015-11-24 11:48:40

标签: ios swift namespaces swift-extensions

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

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"

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

3 个答案:

答案 0 :(得分:6)

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

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) // -> ???

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

screenshot

答案 1 :(得分:1)

经过一些实验后,我发现的唯一方法是只将其中一个框架导入您的源文件。

答案 2 :(得分:0)

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

因此,在这一刻,您有3个选择:

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

看到现在我必须将我的代码的所有调用更改为myBytes,并且我具有实现此调用的源代码,因此即使您不能执行1或2(因为麻烦很多)也不会发生更多冲突。如果您不能做这三项中的任何一项,我想那是没有解决办法的。

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