第 3 篇:认识 dd-plist —— 它到底是个什么库
本系列第 3 篇。动手翻译前,必须先搞懂原库解决什么问题。这篇用大白话把 plist 和 dd-plist 讲明白。
一、先搞懂:plist 是什么?
plist = Property List(属性列表),是苹果生态(macOS / iOS)里最常见的配置文件 / 数据存储格式。
你可以把它理解成苹果版的 JSON——作用和 JSON、XML 一样,就是存一堆有结构的数据,比如:
- App 的配置信息(
Info.plist,每个 iOS / Mac 应用里都有一个) - 用户的偏好设置
- 一些序列化保存下来的数据
举个直观例子,一个 plist 存的东西大概是这样(先用「人话」表示):
{
姓名: "张三"
年龄: 23
注册时间: 2011-02-13
照片: <一堆二进制数据>
爱好: ["篮球", "编程"]
}二、麻烦的地方:同一份数据有 3 种「写法」
plist 棘手的点在于:同一份数据,可以用三种完全不同的格式存进文件。
| 格式 | 长什么样 | 特点 |
|---|---|---|
| XML 格式 | <dict><key>Name</key><string>张三</string>... | 人能看懂,就是标签啰嗦 |
| Binary 格式 | bplist00... 一堆二进制乱码 | 机器读,文件小、解析快 |
| ASCII 格式 | { Name = "张三"; Age = 23; } | 老式风格,像简化版 JSON |
三种格式表达的是同一份数据,只是「外表」不同。 你打开一个 .plist 文件,可能是这三种里的任意一种。
来看原库 test-files/ 里的真实例子,同一份数据的两种写法:
XML 写法(test1.plist):
<dict>
<key>keyA</key>
<string>valueA</string>
<key>keyB</key>
<string>value&B</string>
</dict>ASCII 写法(test1-ascii.plist):
{
keyA = valueA;
keyB = "value&B";
}看到没?一模一样的数据,两种外表。
三、dd-plist 到底做了什么?
它就是一个 「plist 文件的翻译官 + 搬运工」,主要做三件事:
🔹 事情 1:读(解析 Parse)
把任意格式的 plist 文件读进来,变成程序里能操作的对象:
plist 文件(不管哪种格式) ──读──▶ 内存里的对象(NSDictionary 等)而且它能自动识别格式——看文件开头几个字节:bplist 开头是二进制、< 开头是 XML、{ 或 ( 开头是 ASCII。
🔹 事情 2:写(生成 Write)
反过来,把内存里的对象输出成任意一种格式:
内存里的对象 ──写──▶ plist 文件(XML / 二进制 / ASCII 任选)🔹 事情 3:转换(Convert)
把一种格式的文件转成另一种。比如把 XML 的 plist 转成体积更小的二进制 plist:
XML 格式文件 ──转──▶ 二进制格式文件四、那些 NS 开头的类是做什么的?
这是这个库的数据模型。因为 plist 里有各种数据类型(字符串、数字、日期、数组……),库里就用一个类对应一种类型。NS 是苹果的命名前缀(NeXTSTEP 的缩写):
| 类名 | 对应数据类型 | 类比 JSON |
|---|---|---|
NSString | 字符串 | "张三" |
NSNumber | 数字(整数 / 小数 / 布尔) | 23 / true |
NSDate | 日期时间 | — |
NSData | 二进制数据(如图片) | — |
NSArray | 数组 / 列表 | ["a", "b"] |
NSDictionary | 字典 / 键值对 | {"k": "v"} |
NSSet | 集合(元素不重复) | — |
NSNull | 空值 | null |
NSObject | 以上所有类的「共同父类」 | — |
所以读一个 plist 文件,最后你拿到的通常是一个 NSDictionary(就像 JSON 解析后拿到一个对象),里面又套着 NSString、NSNumber、NSArray 等等,层层嵌套。
五、一段真实代码感受一下
原库 README 里的写入例子(Java),能直观看到「构造对象 → 输出文件」的过程:
// 创建根对象(一个字典)
NSDictionary root = new NSDictionary();
NSDictionary person = new NSDictionary();
person.put("Name", "Peter"); // 自动包装成 NSString
person.put("Age", 23); // 自动包装成 NSNumber
root.put("Person", person);
// 输出成 XML 格式的 plist 文件
XMLPropertyListWriter.write(root, new File("people.plist"));我们要做的,就是让仓颉也能写出类似这样的代码。
六、一句话总结
dd-plist 就是一个处理苹果
.plist配置文件的工具库:能读(3 种格式自动识别)、能写(生成 3 种格式)、能互转,并用一套NS*类在内存里表示这些数据。
而我们的任务,就是把这个「plist 工具库」用仓颉语言重新实现一遍,让仓颉程序也能读写 plist 文件。
七、这一步的收获
- 搞懂了原库的输入输出:文件 ⇄
NS*对象 ⇄ 三种格式。 - 搞懂了
NS*类的分工:一个类对应一种数据类型,NSObject是它们的爹。 - 心里有了一张「地图」,下一步就能规划先翻哪个、后翻哪个了。
下一篇:通读源码,规划移植路线 —— 面对 28 个陌生文件、近万行代码,怎么理出翻译顺序和难点。