解决字体缓存问题

教程
作者:Rainer Erich Scheichelbauer
en fr zh

4 六月 2017 发布日期: 24 五月 2013

Re-installing a font in Font Book can create font cache troubles. Here is how to avoid it.

如果你想在实际使用中测试字体,而且考虑使用 Adobe 应用程序,那么,你可以使用 Adobe 字体文件夹,并从一开始就规避掉缓存问题。祝贺你:你不需要再读下去了,问题解决!

在非 Adobe 应用程序中测试

不过我们假设你决定在诸如 “文本编辑” 或 Word 中测试字体。所以,你通过 Apple 的 “字体册” 应用程序将字体安装在系统中,或使用第三方的字体管理工具,或者直接将字体文件拖动到 ~/Library/Fonts/ 中。

那个,你不应该这样做。

为什么不行呢?因为安装一款和之前安装过的同名的字体会严重搞乱你的字体缓存。缓存是之前运算数据的收集。它们可以加速计算机的运行,因为这样它就不需要每次重新运算原始信息了。类似地,字体缓存让你的 Mac 可以加速已安装字体的使用速度,因为 Mac 要让你的字体显示在屏幕上所需要的运算都已经完成了。

不过当然了,原始字体已经改变,但缓存对此一无所知,那么其中存储的数据就变成了过时且错误的数据。典型症状包括:

  • 字体菜单不再显示你的字体
  • 字符形不显示
  • 你对字体所做的修改没有在屏幕上显示
  • 字符形显示出错,在屏幕上出现混乱
  • 你键入一个字母,但出现的是另一个字母
  • 段落不会正常地重新组织
  • 你的字体无法被打印出来,或打印出来的是错误的字母

或者其他任何字体上的怪事,说真的。

清除缓存

如果你遇到了这种问题,从字体册或是任何你使用的第三方工具中删除字体。重要:不要只是停用,要移除它。之后,你有两个选择:

第一道防线:按住 Shift 重启

重启 Mac 时按住 Shift 键直到屏幕上显示 “安全模式”。按住 Shift 重启会让你的 Mac 删除并重建缓存,其中也包括字体缓存。当你的登陆画面出现时,登陆你的用户,并再次重启,这次不按 Shift 键。

重要:重启两次是必要的,因为第一次重启(按住 Shift)删除恶之根源——字体缓存。但因为它是在安全模式下重启,一些内核功能扩展不会加载,你的 Mac 可能不会像平常一样表现出色和活泼。因此,第二次重新启动(不按 Shift)将再次正常启动 Mac。

你的 Mac 可能会忙碌一会儿,因此你会看到在几分钟内有更多硬盘和 CPU 活动。这没问题,因为它在重建缓存。

让 Apple 字体服务器清除其数据库

如果这样做没有帮助,或者如果你只是不想重新启动两次,请打开 “终端”(你可以在 /应用程序/实用工具/ 中找到它)并键入(或拷贝粘贴)以下命令。如果你键入,每行之后必须按下 Return 键结束;如果粘贴,则会需要按 Return 键确认第三行的输入。第一行代码将提示你输入密码。请注意,你不会看到 “密码圆点”(•••)指示密码长度。仍然键入并按回车键确认:

sudo atsutil databases -remove
atsutil server -shutdown
atsutil server -ping

现在,重启 Mac。不,真的,打开左上角的苹果菜单并选择 “重新启动”。别以为你不用重启就能解决问题,不然麻烦还会出现。你不想这样,对不对?行,重启 Mac 吧。

使用一个 AppleScript 脚本清理缓存

由于你在使用 Mac,因此可以将这些确切的命令放在 AppleScript 脚本中,并在脚本菜单中方便地使用它。因此,你无需记住终端里的咒语,或回来再次寻找这篇文章。

好,我们开始干。在 “访达” 中,选择 “前往 > 实用工具”(Cmd-Shift-U)并双击名为 “脚本编辑器” 的应用程序:

通过 “文件 > 新建”(Cmd-N)创建新脚本,在新窗口中拷贝粘贴以下内容:

try
    do shell script "sudo atsutil databases -remove" with administrator privileges
on error errMsg number errNum
    display dialog "Font cache error " & errNum & ": " & errMsg
end try
do shell script "atsutil server -shutdown"
do shell script "atsutil server -ping"
set buttonAnswer to text of button returned of (display dialog "It is strongly recommended that you restart your Mac, or at least log out and back in again." with title "Font caches cleaned" with icon caution buttons {"Restart", "Log out", "Later"} default button 3)
if buttonAnswer is "Log out" then
    tell application "System Events" to log out
else if buttonAnswer is "Restart" then
    tell application "System Events" to restart
end if

按下带锤子图标的按钮(“编译脚本”)来确认代码。代码应该会按句法显示颜色:

在你的用户脚本文件夹中保存脚本。为此,选择 “文件 > 移到…”,在随后出现的对话框中,按下 Cmd-Shift-G 唤出 “前往文件夹” 对话框。在这里,拷贝粘贴这行内容:

~/Library/Scripts/

这样做时,效果如下:

按下 “前往”,“移到” 对话框会显示用户的 Scripts 文件夹,这就是你要移动脚本前往的地方。所以你现在可以安全地按下 “移动” 了。

不要忘记将其重命名为有意义的名称。 选择 “文件 > 重命名…”,并将其命名为 Clean Font Caches.scpt 之类的。 完成后,请开启 “脚本” 菜单,以便你可以在需要时轻松访问 AppleScript 脚本。为此,请通过 “脚本编辑器 > 偏好设置…”(Cmd-逗号)访问首选项,转到 “偏好设置” 窗口的 “通用” 选项卡,并确保勾选 “在菜单栏中显示脚本菜单” 旁边的复选框:

Mac 在屏幕的右上角显示一系列菜单栏项目,其中一个便是脚本菜单。它允许你运行保存在特殊文件夹中的 AppleScript 脚本,其中之一为 〜/ Library / Scripts /。因此,当你单击它时,就应该能看到我们刚刚保存在此处的 AppleScript 脚本:

现在你可以:

  1. 从系统中移除字体,
  2. (通过脚本菜单)运行脚本来清除字体缓存,
  3. 重启 Mac(脚本提供你立即重启的选项),
  4. 安装你字体的更新版本。

避免缓存问题

有几种简单的办法来实际地从一开始就避免缓存问题。首先,如本文开头所述,在 Adobe 应用程序中测试字体。Adobe 应用程序有一个特殊的 Fonts 文件夹,保存在这些文件夹中的字体会立刻在 Adobe 应用程序中激活,最重要的是,不会被缓存。

其次,如果你确实必须在系统中测试字体,那么每次安装字体时,请更改家族名称。你可以用数字或字母扩展名称。由于字体缓存链接到字体名称,因此使用不同名称的新字体安装将不会与以前的安装冲突。唯一的缺点:经过几次迭代,你会将字体菜单弄到得难以处理的程度。

其三,也许也是最好的选择,就是使用我们为此目的而创建的小工具 TextPreview 。它可以监视文件夹中添加的新字体,并使它们在应用程序中可用而无需安装。在我们的 Tools 页面上找到该应用程序。

解决方法:使用更改过的文件名导出

Nico Hagenburger 发现,macOS 字体缓存取决于字体文件的文件名。因此,如果确保每次导出时导出的 OTF 都有不同的文件名,并且删除所有以前的版本,那就应该没问题了。Nico 很善良地编写了一个名为 Export and Install 的 Python 脚本,正是用于完成这一任务。跟随链接获取更精确的描述和安装说明。

注意:我们仅能为 macOS 10.13 以及更新的版本确认这一解决方法的可靠性。我们收到了来自旧 macOS 版本用户的否认报告。有时它会起作用,有时则不会。偶尔你仍需重启使用该字体的应用程序。


示例字体:ALENA,由 ROLAND STIEGER 设计
2013-07-04 更新:指明在哪里删除字体。
2014-06-16 更新:去除了多余的特定于用户的缓存清理,sudo 行删除所有缓存。
2016-01-02 更新:添加了前往 “Adobe 字体文件夹” 教程的链接。
2016-02-19 更新为 Glyphs 2 截图。
2017-06-04 更新:为更加明晰而部分重写,更新了截图,添加了 TextPreview。
2018-06-06 更新:添加了 “解决方法:使用更改过的文件名导出”。(感谢 Nico!)
2019-02-25 更新:添加了 “按住 Shift 重启”。

Chinese translation by Willie Liu (刘育黎) from 3type (三言).