两个可选计算属性代码块:为何.first的两种写法效果不等价?
为什么两段计算属性代码效果截然不同?
嘿,这个问题挺有意思的!我来帮你拆解一下为什么这两段看似等价的代码会有完全不同的表现~
先把两段代码摆出来对比:
第一段代码:
private var oneAndOnly { get { let faceCardIndices = cards.indices.filter({cards[$0].isFaceUp}) return faceCardIndices.count == 1 ? faceCardIndices.first : nil } }
第二段代码:
private var oneAndOnly { get { return cards.indices.filter({cards[$0].isFaceUp}).first } }
你说的“空集合时first返回nil”没错,但你忽略了非空但元素数量大于1的场景,这正是二者的核心差异:
- 第一段代码:只有当翻面卡片的数量恰好为1时,才返回对应的索引;如果是0张或者≥2张,都会返回
nil。 - 第二段代码:只要存在至少1张翻面卡片,就返回第一个符合条件的索引;只有当0张翻面时才返回
nil。
那为什么第二段会卡顿?
大概率是你的后续业务逻辑完全依赖这个oneAndOnly的返回值。举个常见的场景:当用户翻第二张卡片时,此时有2张卡片处于翻面状态:
- 第一段代码返回
nil,你的逻辑会进入“处理两张卡片匹配”的正确分支,不会触发多余的操作; - 第二段代码会返回第一张翻面卡片的索引,这会让你的逻辑误以为当前还有“唯一待匹配”的卡片,进而触发重复的状态检查、视图刷新甚至是无限循环——比如反复尝试用刚翻的卡片和这个返回的索引卡片匹配,导致主线程被持续占用,最终出现卡顿。
简单说,两段代码的行为差异直接导致了后续逻辑的走向完全不同,这就是你看到卡顿的根源。
内容的提问来源于stack exchange,提问作者Turnipdabeets
相关产品推荐
相关产品推荐

