swift-tsao 3.0.2

swift-tsao 3.0.2

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布上次发布2017年3月
SwiftSwift版本3.0
SPM支持SPM

Lily Ballard 维护。



  • 作者
  • Kevin Ballard

No. 型安全关联对象在 Swift

TSAO 是 Swift 中类型安全关联对象的一种实现。Objective-C 关联对象非常有用,但它们也是未类型的;在编译时,每个关联对象只知道是 id,客户端必须要么在运行时检查类,要么依赖于它期望的类型。

Swift 允许我们做得更好。我们可以将值类型与用于引用值的键关联起来,这样可以让我们在编译时提供强类型值,而没有任何运行时开销¹。更重要的是,它可以允许我们将值类型作为关联对象存储,而不仅仅是对象类型,通过透明地装箱值(尽管这涉及到堆分配)。我们还可以反转关联对象的常规工作方式,并使用从 AnyObjectValueType 的全局映射语义提供此类型安全适配器。

还可以指定关联策略。对所有值,支持 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
}