解决|解决 SourceKitService 内存占用过高

SourceKitService 是用来服务于解析 Swift 代码格式的,和 Swift 的代码着色、类型自动推断等特性息息相关,如果我们在活动监视器中强制停止掉这个服务,那么会发现 Xcode 中 Swift 代码大部分都会变成白色,并代码提示和类型推断都失效了。
但是在我今天写代码的时候发现,这个服务突然占用了很高的 CPU 以及内存,曾一度达到 201% 和 5.7GB 的占用率,直接导致了无法编译、没有代码提示等问题。
搜索了一些资料后,网络上给出了两个具体的方案,根据这篇问题:https://stackoverflow.com/questions/26151954/sourcekitservice-consumes-cpu-and-grinds-xcode-to-a-halt
回答中指出了,首先可以尝试删除这个服务产生的缓存,然后手动终止掉这个服务,等待 Xcode 重新开启,可能会解决。
第二个办法就是,因为这个服务的天生缺陷,在进行复杂的字面量类型推断时,可能会造成占用大量资源,具体一点讲就是在写一个很长的数组时,不要写成以下这样:

let array = ["": [""], "": [""], "": [""], "": [""], "": [""], "": [""] ... ]

而是要给一个明确的类型,帮助 Xcode 进行推断:
let array: [String: [String]] = ["": [""], "": [""], "": [""], "": [""], "": [""], "": [""] ... ]

道理是这么个道理,但是我检查了我的代码之后,发现并没有类似的写法的数组,甚至连长数组都没有,就算给所有数组都手动加上类型,也无济于事。
后来发现,不光是数组,普通的变量频繁的进行“串联推断”也会导致这个问题,具体例子如下:
let userToken = (dataModel?.id ?? "") + (dataModel?.token ?? "") + (dataModel?.timestamp ?? "") + ...

这种写法同样会增加自动类型推断的负担,偶尔甚至会造成代码不能通过编译阶段。
所以,我改成了这种写法:
let userID = dataModel?.id ?? "" let token = dataModel?.token ?? "" let timestamp = dataModel?.timestamp ?? "" ... let userToken = userID + token + timestamp + ...

经过改动之后,一切回归正常。
【解决|解决 SourceKitService 内存占用过高】明明是想偷个懒,不想多写那么多属性,结果反而造成了雪崩式的麻烦,Xcode 瞬间变成了全球最大的 TXT 编辑器,看来以后还是要多注意一下规范问题啊~

    推荐阅读