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

Swift中检测类型类一致性、安全遵循AnyObject的实现方案

编者注:评论中提及的此前答案并未解答核心问题:如何判断任意给定Type是否为引用类型,以及如何让该类型安全遵循AnyObject。

直接对传入类型做检测无法生效,因为底层类型可能是可选类型,也可能是协议,这类场景下需要判断传入的实例是类类型还是值类型。

笔者梳理的解决方案与下文给出的修订答案思路相近。


问题场景

我开发了一款全新的依赖注入框架Factory。

Factory支持作用域实例能力,本质是在服务创建完成后对其进行缓存。其中一类作用域为shared:只要外部存在对共享实例的强引用,该实例就会被缓存并复用;当最后一个强引用释放后,缓存也会释放该实例,下一次解析时将创建新实例。

该能力的实现逻辑非常直观:对创建的对象维持弱引用即可,若弱引用为nil则重新创建对象。
但该实现存在核心问题:弱引用仅能作用于引用类型。

Factory内部通过泛型管理类型信息,支持创建任意类型的实例:类、结构体、字符串等均可支持。
作用域内部使用装箱类型的字典存储实例,若缓存和装箱容器中存在对应实例则直接返回。我最初期望实现如下代码:

private struct WeakBox<T:AnyObject>: AnyBox {
    weak var boxed: T
}

声明T遵循AnyObject是为了支持弱引用,否则会触发编译器报错。随后我期望通过如下代码在shared作用域中装箱并缓存对象:

func cache<T>(id: Int, instance: T) {
    cache[id] = WeakBox(boxed: instance)
}

但上述代码同样会触发编译器报错:泛型结构体WeakBox要求T必须是类类型。

现有尝试与问题

如何实现两类类型的桥接?如下写法无法生效,Swift会抛出警告“从'T'到'AnyObject'的条件转换始终成功”,并直接完成类型转换:

func cache<T>(id: Int, instance: T) {
    if let instance = instance as? AnyObject {
        cache[id] = WeakBox(boxed: instance)
    }
}

我也尝试过如下写法,但存在同样问题:无法检测类型是否符合类一致性,也无法通过条件转换判断是否遵循AnyObject,该转换始终会成功:

private struct WeakBox: AnyBox {
    weak var boxed: AnyObject?
}
func cache<T>(id: Int, instance: T) {
    if let instance = instance as? AnyObject {
        cache[id] = WeakBox(boxed: instance)
    }
}

目前我采用的临时实现如下:

private struct WeakBox: AnyBox {
    weak var boxed: AnyObject?
}
func cache<T>(id: Int, instance: T) {
    cache[id] = WeakBox(boxed: instance as AnyObject)
}

该实现虽然可以运行,但其中instance as AnyObject的转换依赖于特殊的Swift与Objective-C桥接行为,稳定性不足。

无法在运行时检测类型的类一致性对开发造成了较大困扰,属于Swift语言的一处明显设计缺陷:既无法完成一致性检测,也无法通过类型转换判定一致性,该场景下需要合规的解决方案。


内容的提问来源于stack exchange,提问作者Michael Long

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:27:23