模块在swift中意味着什么?

时间:2018-01-24 15:43:29

标签: swift

例如,我有两个名为file1.swift和file2.swift的文件。

file1.swift

import UIKit

class A: B {
}

file2.swift

import UIKit

class C: A{     
}

我正在读的公共类不能在模块之外进行子类化。这里我有子类C.我试图理解模块在这里意味着什么。我为这两个文件导入了相同的模块UIKit。那么这两个文件是同一个模块吗?这样我就可以继承了。或者两个文件都有不同的模块,即使我导入相同的UIKit?

有人可以解释什么是模块吗?

来源:

具有公共访问权限或任何更严格的访问级别的类只能在定义它们的模块中进行子类化。

具有公共访问权限或任何更严格的访问级别的类成员只能在定义它们的模块中被子类覆盖。

2 个答案:

答案 0 :(得分:11)

  

模块是一个代码分发单元 - 一个框架或应用程序,它作为一个单元构建和发布,可以通过Swift的import关键字由另一个模块导入。

     

Xcode中的每个构建目标(例如应用程序包或框架)在Swift中被视为一个单独的模块。如果您将应用程序代码的各个方面组合在一起作为一个独立的框架 - 也许是为了跨多个应用程序封装和重用该代码 - 那么您在该框架中定义的所有内容都将在导入并在应用程序中使用时成为单独模块的一部分,或者当它在另一个框架中使用时。

docs所示,模块是应用程序或框架(库)。如果您使用类AB创建项目,则它们是同一模块的一部分。 相同项目中的任何其他类都可以从这些类继承。但是,如果您将该项目导入另一个项目,则该另一个项目中的类将无法继承AB。为此,您必须在声明之前添加open指示符。

基本上,如果您使用单个应用程序,那么您正在使用单个模块,除非声明为privatefileprivate,否则这些类可以相互子类化。

修改

让我们在模块(项目) Module1

中有以下课程
class A {
}

由于此类不是open,因此只能在同一模块中进行子类化。这意味着下课:

class B: A {
}

可以在 Module1 中的同一项目中编写

如果您将 Module1 添加为项目 Module2 的依赖项,并尝试执行此操作:

import Module1

class C: A {
}

它不会编译。这是因为类A不是open(换句话说,它有public或更少的访问权限)并且它不属于与C相同的模块。 A属于 Module1 C属于 Module2

注意

import关键字将依赖项模块导入当前模块。如果在项目中编写import UIKit,则告诉编译器您要在模块中使用模块UIKitimport未定义当前模块。当前模块是当前项目。

在文件开头添加import UIKit不会更改,也不会定义文件所属的模块。它只是告诉编译器在那个文件中你想使用UIKit模块中的代码。

答案 1 :(得分:1)

Swift 模块(.swiftmodule)

历史:

#include => #import => Precompiled Headers .pch => @import Module(ObjC); => import Module(Swift)

[#include vs #import]
[Precompiled Headers .pch]
[@import Module(ObjC);]

有两种类型

  • .swiftmodule 文件夹。文件夹包含架构和其他元信息的所有 .swiftmodule 文件,例如:

    • .swiftmodule 文件。它是二进制文件格式,其中包含框架公共 API 的抽象语法树 (AST) 或 Swift 中间语言 (SIL)。
    • .swiftdoc - 消费者可以恢复的附加文档
    • .swiftinterface - 模块稳定性

[.swiftinterface or Swift Module Interfaces] 是改进闭源兼容性的下一步

当您Jump to Definition导入模块实际上是在查看.modulemap的公共接口

二进制(库,框架)可以包含多个模块,每个模块可以包含一种子模块(来自Objective-C世界)思想。

import struct SomeModule.SomeStruct

这些模块可以相互依赖。

  • 模块是一组源文件,它解决了相同的问题,这就是为什么它们可以分组在相同的模型名称下。
  • 模块有助于对源进行分组以重用它们
  • 模块帮助 Xcode 最小化构建时间(开源)(如果模块未更改,则不应重新编译)

Module 也是一种作用域,可以帮助编译器确定使用哪个类。如果两个模块使用相同的名称,您会得到

Ambiguous use of 'foo()'

可以通过以下方式解决:

import ModuleName1
import ModuleName2

func someFunc() {
    ModuleName1.SomeClass.foo()
    ModuleName2.SomeClass.foo()
}