应用程序

时间:2019-02-12 15:52:59

标签: swift frameworks

好的...这很难解释(并且很难给它起一个标题),但是我会尽力而为。

我们在使用Carthage导入东西时首先发现了这一点,但是在Xcode中设置了一个示例项目(不使用Carthage),似乎做了相同的事情。

首先,这是我们设置的示例项目的屏幕截图...

enter image description here

具有目标 Test20000 ,并且具有依赖项 A

A 框架然后依赖于 B

重要

Test20000 应用没有添加 B 作为直接依赖项。

框架

B 中有一个类似...的结构

import Foundation

public struct BType {
    public let value = "Hello, B!"
}

A 中,有一个类似...的文件

import Foundation
import B

public struct AType {
    public let value = "Hello, A!"

    public func doAThing() {
        print(BType().value)
    }
}

应用

现在,在 Test20000 应用中,我们可以执行以下操作...

import Foundation
import A

struct TestType {
    func doSomething() {
        let aType = AType()

        print(aType.value)
        aType.doAThing()
    }
}

这按预期工作。它会打印...

  

你好,A!   你好,B!

如果我将功能更改为这样的话...

import Foundation
import A

struct TestType {
    func doSomething() {
        let bType = BType()

        print(bType.value)
    }
}

这将不会编译,因为未导入 B ,因此无法访问BType

抓住!

但是!如果您在 B 中声明扩展名,例如...

extension String {
    func doAThingInB() {
        print(self)
    }
}

然后...在不更改导入和依赖项的情况下,我现在可以将应用程序代码更改为...

import Foundation
import A

struct TestType {
    func doSomething() {
        "Hello, bug!".doAThingInB()
    }
}

这将打印出来,就像扩展名是实际应用程序公共的一样。从B到A,再到应用程序,都是“兔子跳”。

我觉得这根本不应该发生。

我们找不到关闭或阻止这种情况发生的方法。

这是一个错误吗?

我们需要做些什么来阻止这种情况吗?

谢谢

2 个答案:

答案 0 :(得分:1)

我试图利用private module maps来隐藏内部框架,使其对A的用户不可见,但运气不佳。可能与[SR-2896] Private modulemaps do no work properly相关。

我想这是目前的预期行为。 swift.org论坛上有多种建议可以实现您想要的东西,例如Namespaces x submodules或更相关的@_exported and fixing import visibility

最后一个的相关部分:

  

当今的Swift的设计更像Java,C#或Python,因为如果您在Foo的实现中导入Bar,则不会影响导入Foo的客户。或者,好吧,它使导入Foo的客户无法看到Bar的顶级名称。

     
      
  1. 您仍然需要使用Bar,因为编译器不会跟踪您是否在Foo的公共界面中使用了其中一种类型。 (这是上一节。)

  2.   
  3. 导入Foo的客户端仍然可以看到Bar中的扩展名,因为编译器无法区分扩展名来自今天。

  4.   导入Foo的客户端仍然可以看到
  5. Bar中的运算符声明,因为编译器以不同于查找顶层所有其他内容的方式来找到运算符。

  6.   

最后一条消息之一:

  

本次讨论的总体结果是,对于Swift vNext来说,做任何聪明的事都不值得:只需添加“仅实现导入”和“导出导入”,其余就暂时解决。

很高兴知道是否有解决方法,但seems like没有解决方法。

答案 1 :(得分:1)

好的...所以Swift团队的回应...

https://bugs.swift.org/browse/SR-9913

这是他们一段时间以来所知道的。而且他们不希望很快修复它。

所以,是的,这是一个错误。 但是,不,没有任何方法可以解决它。

我猜想修复它所引起的问题要比解决更改方面的问题多。