从 Swift 5 开始,库能够声明稳定的 ABI,允许库二进制文 件替换为更新版本,而无需重新编译客户端程序。
环境变量:BUILD_LIBRARY_FOR_DISTRIBUTION
App链接了1.0动态库生成App产物,当动态库更新到2.0时,只需要重新编译动态库,App不需要重新编译。
创建一个macos命令行项目,添加workspace,再创建一个framework添加到workspace,语言都选swift。
在framework创建一个swift文件,写上代码:
public struct Person {
public init() {}
public var num1 = 1
}
在framework的target的buildsettings中搜索BUILD_LIBRARY_FOR_DISTRIBUTION,看到这个环境变量默认值是NO。
在main文件中写入下面代码:
import Framework
print(Person().num1)
两个project没有添加任何关联依赖,先选择framework进行编译,然后再运行App,可以看到打印1
这时候把Person代码进行修改:
import Foundation
public struct Person {
public init() {}
public var num2 = 2
public var num1 = 1
}
再编译framework,然后选择App scheme,选择Project -> Perform Action -> Run Without Building,可以看到打印结果变成了2。
这是因为swift是一门静态语言,在编译的时候就确定了你动态库里面的存放方式,在调用的时候,识别的是你结构体里面的第一个属性,所以打印出来变成了2。如果把num2改成字符串,打印出来就是一个乱码数字。
swift在5.0以后,不管你哪个版本编译framework,只要你开启BUILD_LIBRARY_FOR_DISTRIBUTION,其他的就不用管了。只要替换现有库的位置即可。
把BUILD_LIBRARY_FOR_DISTRIBUTION修改为YES后,第一次一定要把App和framework编译一下,它才能确定哪些是需要运行时才确定的类型。把类型推到运行时又会导致运行速度变慢,swift提供了关键字@frozen,可以把你的库里面不想推到运行时的东西给冻住,冻住之后就不能像刚才那样推到运行时决定了。