Swift 宏,用于允许在类扩展中进行变量声明。它通过包装 objc_getAssociatedObject
/objc_setAssociatedObject
来实现。
.package(url: "https://github.com/p-x9/AssociatedObject", from: "0.10.3")
将以下内容添加到您的 Podfile
中。
pod 'AssociatedObject', git: 'https://github.com/p-x9/AssociatedObject', tag: '0.10.3'
在 pod install
后,您可以在您的项目中使用此宏。
此外,如果您遇到类似 Expansion of macro 'AssociatedObject' did not produce a non-observing accessor
的构建错误。您应该检查您的项目设置 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 中,不可能同时实现 willSet
和 didSet
以及 setter,因此它们被扩展如下。
@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