这是一个简单但完整的例子,源自jckarter的答案.
它显示了如何将新属性添加到现有类.它通过在扩展块中定义计算属性来实现.computed属性存储为关联对象:
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))
}
}
}
Run Code Online (Sandbox Code Playgroud)
之前关于 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, 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));
}
Run Code Online (Sandbox Code Playgroud)
接下来,您将从程序的其余部分调用 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)
}
Run Code Online (Sandbox Code Playgroud)
最后,一个用于将特定视图控制器的视图标记为“调试”的示例。
// 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)")
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法允许您将nilfor传递value给 setter 以清除键的值,并从 getter 返回一个可选值。另请注意,key两种情况下的参数必须相同 (k1 === k2),而不仅仅是等效 (k1 == k2)。
另请注意,这仅允许您标记 NSObject 或其子类的实例 - 它不适用于 Swift 原生类。它还value必须是 NSObject 子类,但字符串和数字文字都会自动桥接到 Objective-C,因此您不需要进行任何显式转换。
| 归档时间: |
|
| 查看次数: |
4181 次 |
| 最近记录: |