有没有办法在Swift中设置关联对象?

来自目标C的您可以objc_setAssociatedObject在2个对象之间调用函数以使它们维护一个引用,如果在运行时您不希望在删除其引用之前也不要破坏某个对象的话,这会很方便。迅捷有与此类似的东西吗?



月关宝盒
浏览 595回答 3
3回答

温温酱

它显示了如何向现有类添加新属性。它通过在扩展块中定义计算属性来实现。计算的属性存储为关联的对象:import ObjectiveC// Declare a global var to produce a unique address as the assoc object handleprivate var AssociatedObjectHandle: UInt8 = 0extension MyClass {    var stringProperty:String {        get {            return objc_getAssociatedObject(self, &AssociatedObjectHandle) as! String        }        set {            objc_setAssociatedObject(self, &AssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)        }    }}编辑:如果需要支持获取未初始化属性的值并避免发生错误unexpectedly found nil while unwrapping an Optional value,则可以按以下方式修改getter:    get {        return objc_getAssociatedObject(self, &AssociatedObjectHandle) as? String ?? ""    }

小怪兽爱吃肉

该解决方案还支持所有值类型,不仅支持自动桥接的值类型,例如String,Int,Double等。包装纸import ObjectiveCfinal class Lifted<T> {&nbsp; &nbsp; let value: T&nbsp; &nbsp; init(_ x: T) {&nbsp; &nbsp; &nbsp; &nbsp; value = x&nbsp; &nbsp; }}private func lift<T>(x: T) -> Lifted<T>&nbsp; {&nbsp; &nbsp; return Lifted(x)}func setAssociatedObject<T>(object: AnyObject, value: T, associativeKey: UnsafePointer<Void>, policy: objc_AssociationPolicy) {&nbsp; &nbsp; if let v: AnyObject = value as? AnyObject {&nbsp; &nbsp; &nbsp; &nbsp; objc_setAssociatedObject(object, associativeKey, v,&nbsp; policy)&nbsp; &nbsp; }&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; objc_setAssociatedObject(object, associativeKey, lift(value),&nbsp; policy)&nbsp; &nbsp; }}func getAssociatedObject<T>(object: AnyObject, associativeKey: UnsafePointer<Void>) -> T? {&nbsp; &nbsp; if let v = objc_getAssociatedObject(object, associativeKey) as? T {&nbsp; &nbsp; &nbsp; &nbsp; return v&nbsp; &nbsp; }&nbsp; &nbsp; else if let v = objc_getAssociatedObject(object, associativeKey) as? Lifted<T> {&nbsp; &nbsp; &nbsp; &nbsp; return v.value&nbsp; &nbsp; }&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; }}可能的 Class扩展(用法示例)extension UIView {&nbsp; &nbsp; private struct AssociatedKey {&nbsp; &nbsp; &nbsp; &nbsp; static var viewExtension = "viewExtension"&nbsp; &nbsp; }&nbsp; &nbsp; var referenceTransform: CGAffineTransform? {&nbsp; &nbsp; &nbsp; &nbsp; get {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getAssociatedObject(self, associativeKey: &AssociatedKey.viewExtension)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; set {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if let value = newValue {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAssociatedObject(self, value: value, associativeKey: &AssociatedKey.viewExtension, policy: objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

浮云间

显然,这仅适用于Objective-C对象。经过一些摆弄之后,以下是在Swift中进行调用的方法:import ObjectiveC// Define a variable whose address we'll use as key.// "let" doesn't work here.var kSomeKey = "s"…func someFunc() {&nbsp; &nbsp; objc_setAssociatedObject(target, &kSomeKey, value, UInt(OBJC_ASSOCIATION_RETAIN))&nbsp; &nbsp; let value : AnyObject! = objc_getAssociatedObject(target, &kSomeKey)}
打开App,查看更多内容
随时随地看视频慕课网APP