其他
用户数十亿的iOS超级应用,10年代码变化,你发现了吗?
截止到2022年,该代码库已经走过了十周年,笔者将对这一演变背后的技术决策以及它们的历史背景进行一些说明。
经过多年的迭代,Facebook代码库与典型的iOS代码库不同:
(1)它包含了C++、Objective-C(++)和Swift。
(2)它有几十个动态加载的库(dylib),以及太多的类,无法一次将它们加载到Xcode中。
(3)苹果SDK的原始使用几乎为零——一切都被内部抽象所包装或替换。
(4)该应用程序大量使用代码生成,这是由我们的自定义构建系统 Buck 推动的。
(5)如果我们的构建系统没有大量缓存,工程师将不得不花一整天时间等待应用程序的构建。
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_SomeClass", referenced from:
objc-class-ref in libFBSomeLibrary-9032370.a(FBSomeFile.mm.o)
int main() {
DoSomething(context);
}
看起来像这样:
int main() {
FBCallFunctionInDylib(
NotOnStatupFramework,
DoSomething,
context
);
}
apple_binary(
name = "Facebook",
...
deps = [
":NotOnStartup#shared",
":FBCamera#shared",
],
)
apple_library(
name = "NotOnStartup",
srcs = [
"SomeFile.mm",
],
labels = ["special_label"],
deps = [
":PokesModule",
...
],
)
$ buck query “deps(:Facebook)”
> :NotOnStartup
> :FBCamera
$ buck query “attrfilter(labels, special_label, deps(:Facebook))”
> :NotOnStartup
{
"functions": {
"DoSomething": Dylib.NotOnStartup,
...
},
"classes": {
"FBSomeClass": Dylib.SomeOtherOne
}
}
static std::unordered_map<const char *, Dylib> functionToDylib {{
{ "DoSomething", Dylib.NotOnStartup },
{ "FBSomeClass", Dylib.SomeOtherOne },
...
}};