How to access the real object/unproxy a NSProxy object?

Is it possible to access the real object/unproxy (not sure what's the right term) a NSProxy object?

I extended a NSView with a property and whenever the property is accessed via the view's animator property (a proxy of the view which uses NSProxy), some of my code isn't behaving correctly. I need to access the real/unproxied view object.

I currently use this workaround to access it:

if self.isProxy(), let view = layer?.delegate as? NSView, view == self {
    // use the view without NSProxy
}

This is a horrible, horrible workaround and it only works as I know that my view is using a layer and that the layers delegate is returning the view.

There might not even be one.

A common use case for proxied objects is to be a facade in front of some IPC mechansim that's talking to an out-of-process service. In the case of CoreAnimation, you're talking to a separate "render server" process.

3 Likes

It's not too bad for what you have to deal with.
This is alternative way if you could have a subclass:

class MyView: NSView {
    @objc private func realSelf() -> MyView { self }
    static func toRealSelf(_ v: MyView) -> MyView {
        v.perform(#selector(realSelf))!.takeUnretainedValue() as! MyView
    }
}
// usage: MyView.toRealSelf(view_or_proxy)

Not a masterpiece either.

Works fine without a subclass too:

extension NSView {
    @objc private func realSelf() -> NSView { self }
    static func toRealSelf(_ v: NSView) -> NSView {
        v.perform(#selector(realSelf))!.takeUnretainedValue() as! NSView
    }
}
// usage: NSView.toRealSelf(view_or_proxy)

You may also put it on the NSObject (which is logical as isProxy is there) and only call through a selector if it's proxy:

extension NSObject {
    @objc private func realSelf() -> NSObject { self }
    static func toRealSelf(_ v: NSObject) -> NSObject {
        v.isProxy() ? (v.perform(#selector(realSelf))!.takeUnretainedValue() as! NSObject) : v
    }
}
// usage: NSObject.toRealSelf(object_or_proxy)
1 Like

thanks. just tested your code and it works.