p-x9 / AssociatedObject

🔗 Swift Macro for allowing variable declarations even in class extensions
MIT License
125 stars 3 forks source link

Any idea why this is error. #21

Open mlch911 opened 7 months ago

mlch911 commented 7 months ago

This code get an error: Value of type '(UIView) -> () -> UIView' has no member 'window'

@AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
private var autoMaskView: UIView = {
    let view = UIView()
    view.bk_(whenTapped: { [weak self] in
        self?.window?.endEditing(true)
    })
    return view
}()

But after I replace the code with the macro expaned code, the error goes away.🤣

static var __associated_autoMaskViewKey: UInt8 = 0
private var autoMaskView: UIView
{
    get {
        if let value = objc_getAssociatedObject(
            self,
            &Self.__associated_autoMaskViewKey
        ) as? UIView {
            return value
        }
        let value = {
            let view = UIView()
            view.bk_(whenTapped: { [weak self] in
                self?.window?.endEditing(true)
            })
            return view
        }()
        objc_setAssociatedObject(
            self,
            &Self.__associated_autoMaskViewKey,
            value,
            .OBJC_ASSOCIATION_RETAIN_NONATOMIC
        )
        return value
    }
    set {
        objc_setAssociatedObject(
            self,
            &Self.__associated_autoMaskViewKey,
            newValue,
            .OBJC_ASSOCIATION_RETAIN_NONATOMIC
        )
    }
}
p-x9 commented 7 months ago

Regardless of Macro, it should not be possible to capture self before Self is initialized.

How about modifying it to assign after initialization as follows?

import UIKit

extension UIView {
    func bk_(whenTapped: () -> Void) {}
}

extension UIViewController {
    @AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    private var autoMaskView: UIView?

    func setup() {
        autoMaskView = { [self] in
            let ss = self
            let view = NSView()
            view.bk_(whenTapped: { [weak ss] in
                self?.window?.endEditing(true)
            })
            return view
        }()
    }
}
mlch911 commented 5 months ago

So the Macro is build before Self is initialized. It's different from just using a computing property, right?

So if I want to capture self, I can't use @AssociatedObject.