具体来说,我想在UIView实例中添加一个枚举类型的变量,而不需要子类化或创建扩展。
谢谢。
谢谢。
以下是一个简单但完整的示例,源自于jckarter的回答。
它展示了如何向现有类添加新属性。这是通过在扩展块中定义计算属性来实现的。计算属性存储为关联对象:
import ObjectiveC
// Declare a global var to produce a unique address as the assoc object handle
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))
}
}
}
关于objc_setAssociatedObject()的先前答案是正确的方法,但是我认为苹果对此的API尚未经过审查,因为我在使用它们时遇到了困难,我认为它们应该被使用。 (我不应该去弄不安全的指针之类的东西。)这是我现在正在使用的解决方案。
首先,您需要一些Objective-C粘合剂(按照苹果的说明在同一个项目中混合使用Objective-C和Swift:
// RuntimeGlue.h
// Should be included from your bridging header.
@import Foundation;
void setAssociatedObject_glue(NSObject *object, const NSString *key, NSObject *value);
NSObject *getAssociatedObject_glue(NSObject *object, const NSString* key);
// RuntimeGlue.m
#import "RuntimeGlue.h"
#import <objc/runtime.h>
void setAssociatedObject_glue(NSObject *object, const NSString *key, NSObject *value) {
objc_setAssociatedObject(object, (__bridge const void *)(key), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
NSObject *getAssociatedObject_glue(NSObject *object, const NSString* key) {
return objc_getAssociatedObject(object, (__bridge const void *)(key));
}
// Runtime.swift
import Foundation
public func setAssociatedObject(#object: NSObject, #key: NSString, #value: NSObject?) {
setAssociatedObject_glue(object, key, value)
}
public func getAssociatedObject(#object: NSObject, #key: NSString) -> NSObject? {
return getAssociatedObject_glue(object, key)
}
// MyViewController.swift
import UIKit
let debugKey: NSString = "DebugKey"
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setAssociatedObject(object: self.view, key: debugKey, value: "debugging")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let val = getAssociatedObject(object: self.view, key: debugKey)
println("val:\(val)")
}
}
value
设置为nil
以清除键的值,并从getter中返回一个可选类型。注意,key
参数在两种情况下必须完全相同(k1 === k2),而不仅仅是等效的(k1 == k2)。
还要注意,这只能标记NSObject或其子类的实例 - 它对Swift原生类无效。 value
必须也是NSObject子类, 但字符串和数字字面量都自动桥接到Objective-C,因此您不需要进行任何显式转换。
objc_setAssociatedObject()
函数将一个对象(您可以将该枚举包装成一个对象)附加到另一个对象上,并使用objc_getAssociatedObject()
检索它。objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC