iOS 代码优化:一键替换count到isEmpty

103 阅读2分钟

有两个正则替换

一、 x.x.count > 0 替换到!x.x.isEmpty

查找替换
((\w+\.)+?)count\s*?>\s*?0!$1isEmpty

二、 x.x.count == 0 替换到x.x.isEmpty

查找替换
((\w+\.)+?)count\s*?==\s*?0$1isEmpty

!!!注意:复制正则时不要三击选择,这样复制文本后缀可能会有空白符

三、 方法

  1. 使用快捷键 Command + Option + F 打开 "Find and Replace" 窗口。
  2. 切换为ReplaceRegular Expression
  3. Replace Expression 输入框中输入正则表达式:((\w+\.)+?)count\s*?>\s*?0
  4. With 输入框中输入替换的内容正则表达式:!$1isEmpty
  5. 点击 Replace All 按钮进行替换。

替换完之后只好检查一下,避免有些替换错误。

四、 为什么要这样做?

通常在判断一个字符串或者数组是否为空的时候有两种方式:count == 0 或者 isEmpty。我们可能会认为两者是一样的,isEmpty 内部实现就是 count == 0。但在 SwiftLint 的检验下,会强制要求我们使用使用 isEmpty 判空。由此可以判断出两者肯定还是存在不同的,今天就来分析下两者的区别。

countisEmpty 这两个属性来源于 Collectioncount 表示数量,这个没啥特别的,需要注意的是isEmpty的实现。在标准库中,它的定义是这样的:

extension Collection {
    var isEmpty: Bool { startIndex == endIndex }
}

集合的首索引和尾索引相等,则表示为空,这里只有一个比较,复杂度为 O(1)

大部分集合类型都是走的该默认实现,但也有一些特定的集合类型会重写该方法,比如 Set

extension Set {
    var isEmpty: Bool { count == 0 }
}

那为啥会出现两种不同的情况呢,我们再看 Collection 里对 count 的说明。

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(n), where n is the length of the collection.

所以对于遵循了RandomAccessCollection 协议的类型,其count获取是 O(1) 复杂度,像是 Array;对于未遵循的类型,比如 String,其 count 复杂度就是 O(n),但是isEmpty 却还是 O(1)。

这里的 Set 还要再特殊一些,因为其没有实现 RandomAccessCollection 却还是用 count 的方式判定是否为空,这是因为 Set 的实现方式不同,其 count 的获取就是 O(1) 复杂度。

当然为了简化记忆,我们可以总是使用 isEmpty 进行判空处理。

因为涉及多个协议和具体类型,这里放一张表示这几个协议和类型之间的关系图。

参考