34

For example, I have two files called file1.swift and file2.swift.

file1.swift:

import UIKit

class A: B {
}

file2.swift:

import UIKit

class C: A{     
}

I am reading that public class can not subclassed outside of module. Here I have subclass C. I am trying to understand what does module mean here. I imported to same module UIKit for both file. So the both files are of same module? So that I can subclassed. Or both files have different module even I import the same UIKit?

Can anybody explain what is module?

Source:

Classes with public access, or any more restrictive access level, can be subclassed only within the module where they’re defined.

Class members with public access, or any more restrictive access level, can be overridden by subclasses only within the module where they’re defined.

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
John
  • 675
  • 1
  • 7
  • 16

2 Answers2

48

A module is a single unit of code distribution—a framework or application that is built and shipped as a single unit and that can be imported by another module with Swift’s import keyword.

Each build target (such as an app bundle or framework) in Xcode is treated as a separate module in Swift. If you group together aspects of your app’s code as a stand-alone framework—perhaps to encapsulate and reuse that code across multiple applications—then everything you define within that framework will be part of a separate module when it’s imported and used within an app, or when it’s used within another framework.

As the docs indicate, the module is an application or a framework (library). If you create a project with classes A and B, they are part of the same module. Any other class in the same project can inherit from those classes. If you however import that project to another project, classes from that another project won't be able to subclass A nor B. For that you would have to add open indicator before their declarations.

Basically, if you work on a single app then you are working in one single module and unless declared as private or fileprivate, the classes can subclass each other.

EDIT

Let us have following class in module (project) Module1:

class A {
}

Since this class is not open, it can be subclassed only within the same module. That means that following class:

class B: A {
}

Can be written only in the same project, in Module1.

If you add Module1 as a dependency to project Module2, and try to do this:

import Module1

class C: A {
}

It will not compile. That's because class A is not open (in other words it has access public or less) and it does not belong to the same module as C. A belongs to Module1, C belongs to Module2.

Note

import keyword imports a dependency module to your current module. If you write import UIKit in your project, you are telling the compiler that you want to use module UIKit in your module. import does not define current module. Current module is the current project.

Adding import UIKit at the beginning of the file does not change nor define to which module the file belongs. It just tells the compiler that in that file you want to use code from UIKit module.

Community
  • 1
  • 1
Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • @John it is explained there, but I added an example to explain it better, read the updated answer – Milan Nosáľ Jan 24 '18 at 16:02
  • I saw open class in using storyboard in playground. Storyboard and playground are different project and then to access superclass , open class used? – John Jan 24 '18 at 16:05
  • @John in my example, if instead `class A { }` you would use `open class A {}`, then you would be able to subclass `A` in other modules that imports *Module1* – Milan Nosáľ Jan 24 '18 at 16:06
  • @John Playground and project with storyboard are two different modules. However, I am not sure if the playground cannot contain a storyboard. But storyboard and classes in the same project belong to the same project – Milan Nosáľ Jan 24 '18 at 16:07
  • @John unless you develop a framework that is meant to be used by other people (imported as dependency) and classes thereof are meant to be subclassed by them, you are good to go with `public` or without a modifier – Milan Nosáľ Jan 24 '18 at 16:08
  • Thank you very much now I understand. Can you look at this file ? Why is there open class in playground please? https://files.fm/u/24xa2nhw – John Jan 24 '18 at 16:14
  • sources/cardController.swift file – John Jan 24 '18 at 16:16
  • @John I have no idea why that's an open class.. If it is defined and implemented in the same module and not used anywhere else, there's no reason for that.. Playgrounds are used to play around with code, not to implement frameworks - therefore I doubt there is any reason to use `open` in any playground code at all – Milan Nosáľ Jan 24 '18 at 16:19
  • Thank you very much. Accepted answer. – John Jan 24 '18 at 16:20
3

Swift module(.swiftmodule)

History:

[#include -> #import] -> [Precompiled Headers .pch] -> [@import Module(ObjC);] -> import Module(Swift)

There are two type of Module - folder and file

  • .swiftmodule folder. Folder contains all .swiftmodule files for architectures and other meta information like:

    • .swiftmodule file. It is binary file format which contains Abstract Syntax Tree(AST) or Swift Intermediate Language(SIL) of framework's public API.
    • .swiftdoc - attached docs which can be revived by consumer
    • .swiftinterface - Module stability

[.swiftinterface or Swift Module Interfaces] is a next step of improving closed source compatibility

When you Jump to Definition of imported module actually you reviewing public interface of .modulemap

Binary(library, framework) can contains several modules, each module can contains a kind of submodule(from Objective-C world) thought.

import struct SomeModule.SomeStruct

These modules can have dependencies between each others.

  • Module is a set of source files which solves the same problem that is why they can be grouped under the same model name.
  • Module helps to group sources to reuse them
  • Module helps Xcode to minimize build time(open source)(If module was not changed it should not been recompiled)

Also Module is a kind of scope which can help compiler to figure out which exactly class to use. If two modules use the same name you get

Ambiguous use of 'foo()'

It can be solved by:

import ModuleName1
import ModuleName2

func someFunc() {
    ModuleName1.SomeClass.foo()
    ModuleName2.SomeClass.foo()
}
yoAlex5
  • 29,217
  • 8
  • 193
  • 205