具体来说,我想将一个enum类型的变量添加到UIView的实例中,而不进行子类化或创建扩展.
谢谢.
关于objc_setAssociatedobject()的前一个答案是正确的方法,但我认为Apple的API尚未经过审查,因为我很难以我认为应该使用它们的方式使用它们. (我不应该用不安全的指针等等.)这是我现在使用的解决方案.
首先,您需要一些Objective-C粘合剂(遵循Apple的说明,在同一个项目中混合使用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,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));
}
接下来,您将从程序的其余部分调用Swift方法:
// 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)")
}
}
此方法允许您将nil for value传递给setter以清除键的值,并从getter返回一个可选项.另请注意,关键参数在两种情况下必须相同(k1 === k2),而不仅仅等效(k1 == k2).
另请注意,这只允许您标记NSObject或其子类的实例 – 它不适用于Swift本机类.该值也必须是NSObject子类,但字符串和数字文字都自动桥接到Objective-C,因此您不需要进行任何显式转换.