oboje / AssociatedObject

πŸ”— Swift Macro for allowing variable declarations even in class extensions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AssociatedObject

Swift Macro for allowing variable declarations even in class extensions. It is implemented by wrapping objc_getAssociatedObject/objc_setAssociatedObject.

Github issues Github forks Github stars Github top language

Usage

For example, you can add a new stored property to UIViewController by declaring the following

import AssociatedObject

extension UIViewController {
    @AssociatedObject(.retain(nonatomic))
    var text = "text"

    /* OR */

    @AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    var text = "text"
}

Declared properties can be used as follows

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        print(text) // => "text"

        text = "hello"
        print(text) // => "hello"
    }

}

willSet/didSet

Properties defined using @AssociatedObject can implement willSet and didSet. In swift, it is not possible to implement willSet and didSet at the same time as setter, so they are expanded as follows.

@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)
    }
}

License

AssociatedObject is released under the MIT License. See LICENSE

About

πŸ”— Swift Macro for allowing variable declarations even in class extensions

License:MIT License


Languages

Language:Swift 100.0%