You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中NSMutableArray在不同iOS版本下的行为差异原因

问题与解答

代码示例

protocol TestProtocol {

}

struct TestStruct: TestProtocol {

}

let arr = NSMutableArray()
let testStruct = TestStruct()
arr.add(testStruct)
print("\(arr[0] is TestProtocol)")

现象差异

  • iOS 14.0及以上版本:输出 true
  • iOS 13版本:输出 false

原因分析

这是Swift与Objective-C桥接逻辑在iOS 14上的修复导致的差异:

  1. 值类型的Objective-C包装:Swift结构体属于值类型,当存入NSMutableArray这类Objective-C容器时,会被自动包装成__SwiftValue对象——这是Swift为了让值类型兼容Objective-C对象体系设计的包装类型。
  2. iOS 13的局限:在iOS 13及更早版本中,Objective-C运行时无法穿透__SwiftValue包装,去识别内部值类型所遵循的协议。执行arr[0] is TestProtocol时,实际检查的是__SwiftValue对象本身是否遵循TestProtocol(它并不遵循),因此返回false。
  3. iOS 14的修复:iOS 14起,苹果优化了桥接逻辑,让协议类型检查能够穿透__SwiftValue包装,直接判断内部的Swift值类型是否符合协议要求,因此此时会返回正确的true。

额外提示:如果使用Swift原生容器(比如Array<TestProtocol>)存储,就不会出现这种跨版本差异,因为原生容器无需Objective-C桥接,能直接识别Swift值类型的协议一致性。

内容的提问来源于stack exchange,提问作者Dmitry Suvorov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:05:30