update: 动态库、静态库的编译链接细节

This commit is contained in:
FantasticLBP
2025-06-23 01:18:55 +08:00
parent aca020701b
commit 1142064d28
129 changed files with 10932 additions and 2615 deletions

View File

@@ -7,7 +7,7 @@
- open允许在定义实体的模块、其他模块中访问允许其他模块进行继承、重写open只能用在类、类成员上)
- public允许在定义实体的模块、其他模块中访问不允许其他模块进行继承、重写
- internal只允许在定义实体的模块中访问不允许在其他模块中访问
- fileprivate只允许在定义实体的源文件中访问
- fileprivate只允许在定义实体的源文件中访问
- private只允许在定义实体的封闭声明中访问
绝大部分实现默认都是 internal
@@ -37,9 +37,9 @@
- 参数类型、返回值类型 >= 函数
- 父类 >= 子类
因为定义的子类如果是 internal而父类是 fileprivate则可以访问到子类的地方访问不到父类这是不合理的。
- 父协议 >= 子协议
协议也可以继承,父协议里的一些属性如果访问级别较低,遵循子协议,实现子协议的类,是无法访问到父协议中的属性的。
- 原类型 >= typealias
```swift
@@ -83,43 +83,50 @@
fileprivate var data1:(Dog, Person)
private var data2:(Dog, Person)
```
- 泛型类型:泛型类型的访问级别由:类型的访问级别以及所有泛型类型参数的访问级别最低的那个决定
Demo1: 编译器报错:`Variable must be declared private or fileprivate because its type uses a fileprivate type`
分析:
- 泛型的访问级别由最低的类别的访问级别决定。Car 为 internalDog 为 fileprivate所以最低的是 fileprivate所以 Person 类型的访问级别为 fileprivate。因此 Person 类型变量的访问级别为 fileprivate 或者比 fileprivate 更低的访问级别。
- Swift 默认所有的变量、方法、类的默认访问级别为 internal。internal 访问级别高于 fileprivate所以报错。
看似规则比较多,实际上就是对「一个实体不可以被更低访问级别的实体定义」的解释。
```swift
internal class Car { }
fileprivate class Dog { }
public class Person<T1, T2> { }
var person: Person<Car, Dog> = Person() // compile error: Variable must be declared private or fileprivate because its type uses a fileprivate type
```
改进下: `fileprivate var person: Person<Car, Dog> = Person()` 和 `private var person: Person<Car, Dog> = Person()` 都不会报错。
类型的访问级别会影响成员(属性、方法、初始化器、下标)、嵌套类型的默认访问级别
- 类型的访问级别会影响成员(属性、方法、初始化器、下标)、嵌套类型的默认访问级别
- 一般情况下,类型为 fileprivate、private那么成员、嵌套类型默认也是 private、fileprivate
- 一般情况下,类型为 internal、public那么成员、嵌套类型默认也是 internal
- 一般情况下,类型为 fileprivate、private那么成员、嵌套类型默认也是 private、fileprivate
- 一般情况下,类型为 internal、public那么成员、嵌套类型默认也是 internal
测试:
```swift
// 编译不通过
class TestClass {
private class Person {}
fileprivate class Student : Person {} // Class cannot be declared fileprivate because its superclass is private
}
测试:
```swift
// 编译不通过
class TestClass {
// 编译通过
private class Person {}
fileprivate class Student : Person {} // Class cannot be declared fileprivate because its superclass is private
}
// 编译通过
private class Person {}
fileprivate class Student : Person {}
```
当 fileprivate、private 都写在文件的全局作用域时,访问权限是一样的。
fileprivate class Student : Person {}
```
- 当 fileprivate、private 都写在文件的全局作用域时,访问权限是一样的。
总结:看似规则比较多,实际上就是对「一个实体不可以被更低访问级别的实体定义」的解释。
## getter、setter
getter、setter 默认自动接收他们所属换的访问级别
可以给 setter 单独设置一个比 getter 权限更低的访问级别,用以限制写权限
- getter、setter 默认自动接收他们所属换的访问级别
- **可以给 setter 单独设置一个比 getter 权限更低的访问级别,用以限制写权限**
```swift
private(set) var num = 10
@@ -146,8 +153,7 @@ print(num)
## 初始化器
- 如果一个 public 类,想在另一个模块调用编译生成的默认无参初始化器,必须显示提供 public 的无参初始化器(因为 public 类的默认初始化器是 internal 级别的)
- 如果一个 public 类,想在另一个模块调用编译生成的默认无参初始化器,必须显示提供 public 的无参初始化器(因为 public class编译器生成的 init 初始化器是 internal。另一个模块是无法访问的
```swift
// APM.dylib
@@ -164,20 +170,13 @@ print(num)
## 枚举类型
不能给 enum 的 case 单独设置访问级别,每个 case 自动对齐 enum 的访问级别
- public 的 enum各个 case 也是 public
不能给 enum 的 case 单独设置访问级别,每个 case 自动对齐 enum 的访问级别比如public 的 enum各个 case 也是 public
## 协议
协议中定义的要求自动接收协议的访问级别,不能单独设置访问级别
- public 定义的协议,各个属性、方法也是 public 级别
协议实现的访问级别 >= 类型的访问级别(协议的访问级别)
协议中定义的要求自动接收协议的访问级别不能单独设置访问级别比如public 定义的协议,各个属性、方法也是 public 级别)
**协议实现的访问级别 >= 类型的访问级别(协议的访问级别**
```swift
// 编译通过