允许在类扩展中声明变量的Swift宏。它是通过包装objc_getAssociatedObject
/objc_setAssociatedObject
实现的。
.package(url: "https://github.com/p-x9/AssociatedObject", from: "0.7.0")
添加以下内容到您的Podfile
。
pod 'AssociatedObject', git: 'https://github.com/p-x9/AssociatedObject', '~> 0.7.0'
在运行pod install
之后,您可以在项目中使用此宏。
另外,如果您遇到了类似“宏'AssociatedObject'的展开没有产生非观察访问器”的构建错误。您应该检查项目设置中的Build Settings
-OTHER_SWIFT_FLAGS
。
如果没有,您可以自己添加以下两行。
-load-plugin-executable
${PODS_ROOT}/AssociatedObject/Binary/AssociatedObjectPlugin#AssociatedObjectPlugin
例如,您可以通过以下声明向UIViewController
添加一个新存储属性
import AssociatedObject
extension UIViewController {
@AssociatedObject(.retain(nonatomic))
var text = "text"
/* OR */
@AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
var text = "text"
static var customKey = ""
@AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC, key: customKey)
var somevar = "text"
}
已声明的属性可以使用如下方式使用
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(text) // => "text"
text = "hello"
print(text) // => "hello"
}
}
使用@AssociatedObject
定义的属性可以实施willSet和didSet。在Swift中,无法将setter与willSet和didSet同时实现,因此它们被展开如下。
@AssociatedObject(.copy(nonatomic))
public var hello: String = "こんにちは" {
didSet {
print("didSet")
}
willSet {
print("willSet: \(newValue)")
}
}
// ↓↓↓ expand to ... ↓↓↓
public var hello: String = "こんにちは" {
get {
objc_getAssociatedObject(
self,
&Self.__associated_helloKey
) as? String
?? "こんにちは"
}
set {
let willSet: (String) -> Void = { [self] newValue in
print("willSet: \(newValue)")
}
willSet(newValue)
let oldValue = hello
objc_setAssociatedObject(
self,
&Self.__associated_helloKey,
newValue,
.copy(nonatomic)
)
let didSet: (String) -> Void = { [self] oldValue in
print("didSet")
}
didSet(oldValue)
}
}
AssociatedObject遵循MIT许可证发布。见LICENSE