3 回答

TA貢獻1752條經驗 獲得超4個贊
它顯示了如何向現有類添加新屬性。它通過在擴展塊中定義計算屬性來實現。計算的屬性存儲為關聯的對象:
import ObjectiveC
// Declare a global var to produce a unique address as the assoc object handle
private var AssociatedObjectHandle: UInt8 = 0
extension 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 ?? ""
? ? }

TA貢獻1852條經驗 獲得超1個贊
該解決方案還支持所有值類型,不僅支持自動橋接的值類型,例如String,Int,Double等。
包裝紙
import ObjectiveC
final class Lifted<T> {
let value: T
init(_ x: T) {
value = x
}
}
private func lift<T>(x: T) -> Lifted<T> {
return Lifted(x)
}
func setAssociatedObject<T>(object: AnyObject, value: T, associativeKey: UnsafePointer<Void>, policy: objc_AssociationPolicy) {
if let v: AnyObject = value as? AnyObject {
objc_setAssociatedObject(object, associativeKey, v, policy)
}
else {
objc_setAssociatedObject(object, associativeKey, lift(value), policy)
}
}
func getAssociatedObject<T>(object: AnyObject, associativeKey: UnsafePointer<Void>) -> T? {
if let v = objc_getAssociatedObject(object, associativeKey) as? T {
return v
}
else if let v = objc_getAssociatedObject(object, associativeKey) as? Lifted<T> {
return v.value
}
else {
return nil
}
}
可能的 Class擴展(用法示例)
extension UIView {
private struct AssociatedKey {
static var viewExtension = "viewExtension"
}
var referenceTransform: CGAffineTransform? {
get {
return getAssociatedObject(self, associativeKey: &AssociatedKey.viewExtension)
}
set {
if let value = newValue {
setAssociatedObject(self, value: value, associativeKey: &AssociatedKey.viewExtension, policy: objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
}

TA貢獻1829條經驗 獲得超4個贊
顯然,這僅適用于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() {
objc_setAssociatedObject(target, &kSomeKey, value, UInt(OBJC_ASSOCIATION_RETAIN))
let value : AnyObject! = objc_getAssociatedObject(target, &kSomeKey)
}
- 3 回答
- 0 關注
- 628 瀏覽
添加回答
舉報