测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | MIT |
发布上次发布 | 2017年3月 |
SwiftSwift版本 | 3.0 |
SPM支持SPM | ✓ |
由 Lily Ballard 维护。
TSAO 是 Swift 中类型安全关联对象的一种实现。Objective-C 关联对象非常有用,但它们也是未类型的;在编译时,每个关联对象只知道是 id
,客户端必须要么在运行时检查类,要么依赖于它期望的类型。
Swift 允许我们做得更好。我们可以将值类型与用于引用值的键关联起来,这样可以让我们在编译时提供强类型值,而没有任何运行时开销¹。更重要的是,它可以允许我们将值类型作为关联对象存储,而不仅仅是对象类型,通过透明地装箱值(尽管这涉及到堆分配)。我们还可以反转关联对象的常规工作方式,并使用从 AnyObject
到 ValueType
的全局映射语义提供此类型安全适配器。
还可以指定关联策略。对所有值,支持 atomic/nonatomic retain。对于类值,也支持 assign。对于 NSCopying
值,支持 atomic/nonatomic copy。
为了正确使用此库,您创建的 AssocMap
值应该是静态的或全局值(它们应该存在于整个程序的生存期内)。您不是必须遵守此规则,但任何丢弃的 AssocMap
都会导致对象泄露(这是在没有运行时惩罚的情况下确保安全的唯一方法)。
¹ 它确实需要进行类型检查,但理论上的优化器应该能够删除此检查。
import TSAO
// create a new map that stores the value type Int
// note how this is a global value, so it lives for the whole program
let intMap = AssocMap<Int>()
// fetch the associated object from `obj` using `intMap`
func lookup_int_object(obj: AnyObject) -> Int? {
// The subscript getter returns a value of type `Int?` so no casting is necessary
return intMap[obj]
}
// set the associated object for `intMap` on `obj`
func set_int_object(obj: AnyObject, val: Int?) {
// The subscript setter takes an `Int?` directly, trying to pass
// a value of any other type would be a compile-time error
intMap[obj] = val
}
// This map stores values of type NSString with the nonatomic copy policy
let strMap = AssocMap<NSString>(copyAtomic: false)
// fetch the associated object from `obj` using `strMap`
func lookup_str_object(obj: AnyObject) -> NSString? {
// The subscrip getter returns a value of type `NSString?`
return strMap[obj]
}
// set the associated object for `strMap` on `obj`
func set_str_object(obj: AnyObject, val: NSString?) {
// The subscript setter takes an `NSString?` directly, trying to pass
// an `Int?` like we did with `intMap` would be a compile-time error
strMap[obj] = val
}