例如,我有两个名为file1.swift和file2.swift的文件。
file1.swift
import UIKit
class A: B {
}
file2.swift
import UIKit
class C: A{
}
我正在读的公共类不能在模块之外进行子类化。这里我有子类C.我试图理解模块在这里意味着什么。我为这两个文件导入了相同的模块UIKit。那么这两个文件是同一个模块吗?这样我就可以继承了。或者两个文件都有不同的模块,即使我导入相同的UIKit?
有人可以解释什么是模块吗?
来源:
具有公共访问权限或任何更严格的访问级别的类只能在定义它们的模块中进行子类化。
具有公共访问权限或任何更严格的访问级别的类成员只能在定义它们的模块中被子类覆盖。
答案 0 :(得分:11)
模块是一个代码分发单元 - 一个框架或应用程序,它作为一个单元构建和发布,可以通过Swift的import关键字由另一个模块导入。
Xcode中的每个构建目标(例如应用程序包或框架)在Swift中被视为一个单独的模块。如果您将应用程序代码的各个方面组合在一起作为一个独立的框架 - 也许是为了跨多个应用程序封装和重用该代码 - 那么您在该框架中定义的所有内容都将在导入并在应用程序中使用时成为单独模块的一部分,或者当它在另一个框架中使用时。
如docs所示,模块是应用程序或框架(库)。如果您使用类A
和B
创建项目,则它们是同一模块的一部分。 相同项目中的任何其他类都可以从这些类继承。但是,如果您将该项目导入另一个项目,则该另一个项目中的类将无法继承A
或B
。为此,您必须在声明之前添加open
指示符。
基本上,如果您使用单个应用程序,那么您正在使用单个模块,除非声明为private
或fileprivate
,否则这些类可以相互子类化。
修改强>
让我们在模块(项目) 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
,则告诉编译器您要在模块中使用模块UIKit
。 import
未定义当前模块。当前模块是当前项目。
在文件开头添加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
这些模块可以相互依赖。
Module 也是一种作用域,可以帮助编译器确定使用哪个类。如果两个模块使用相同的名称,您会得到
Ambiguous use of 'foo()'
可以通过以下方式解决:
import ModuleName1
import ModuleName2
func someFunc() {
ModuleName1.SomeClass.foo()
ModuleName2.SomeClass.foo()
}