AssociatedObject 0.8.0

AssociatedObject 0.8.0

Lorpaves维护。



  • p-x9

AssociatedObject

允许在类扩展中声明变量的Swift宏。它是通过包装objc_getAssociatedObject/objc_setAssociatedObject实现的。

Github issues Github forks Github stars Github top language

安装

SPM

.package(url: "https://github.com/p-x9/AssociatedObject", from: "0.7.0")

CocoaPods

添加以下内容到您的Podfile

pod 'AssociatedObject', git: 'https://github.com/p-x9/AssociatedObject', '~> 0.7.0'

在运行pod install之后,您可以在项目中使用此宏。

另外,如果您遇到了类似“宏'AssociatedObject'的展开没有产生非观察访问器”的构建错误。您应该检查项目设置中的Build Settings-OTHER_SWIFT_FLAGS

应该有额外的标志,如下所示。 Alt text

如果没有,您可以自己添加以下两行。

-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"
    }

}

willSet/didSet

使用@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