[swift-dev] NSProxy dynamic casting to Swift or ObjC class behaves differently

Yavuz Nuzumlalı manuyavuz at gmail.com
Wed Jun 8 14:17:47 CDT 2016


Hmm, interesting.

So, we can say that NSProxy class, which is the base structure for
implementing proxy pattern, will not work for a Swift type, right? And I
simply can't use proxy pattern if real object can be a Swift type.

In my use case, I have a framework, and I want to switch developer's some
delegate object with my NSProxy standin, listen delegate method myself,
then forward to the developer's original delegate object.

It was working without any issues for delegate objects which are
Objective-C classes. But, it fails for Swift types because dynamic casting
does not work anymore.

So, do you have any suggestions about how can I handle this interception
functionality without NSProxy?

I don't want to do swizzling :)

Thanks for the explanations!

On Wed, 8 Jun 2016 at 21:13, Jordan Rose <jordan_rose at apple.com> wrote:

>
> On Jun 8, 2016, at 10:52, Joe Groff via swift-dev <swift-dev at swift.org>
> wrote:
>
>
> On Jun 8, 2016, at 12:44 AM, Yavuz Nuzumlalı via swift-dev <
> swift-dev at swift.org> wrote:
>
> Hi all,
>
> swift_dynamicCastClassUnconditional and
> swift_dynamicCastObjCClassUnconditional methods behave differently while
> verifying casting.
>
> swift_dynamicCastObjCClassUnconditional method calls -isKindOfClass:
> method before falling back to object_getClass function.
>
> swift_dynamicCastClassUnconditional method calls swift_dynamicCastClass
> method which calls _swift_getClassOfAllocated method which calls directly
> object_getClass function.
>
> This causes problems if underlying object is an NSProxy subclass.
>
> NSProxy class does not implement -isKindOfClass: method, so calls to this
> method are forwarded to the real object through -forwardInvocation: method,
> which causes -isKindOfClass: method to return answer according to the real
> object's class.
>
> However, object_getClass function directly accesses to the metadata of the
> given object, so it returns NSProxy subclass.
>
> I think this is a conflicting behavior, and I think
> swift_dynamicCastClassUnconditional method should also verify first using
> -isKindOfClass: method, in order to provide consistency.
>
>
> This is intentional, since NSProxy instances are generally expected to be
> standins for the proxied object. Important Cocoa idioms break down if the
> "real" class is exposed instead of the class a proxy pretends to be.
>
>
> For a little more detail, Swift relies on a bit more information about
> layout of both instances and classes than Objective-C does, so an NSProxy
> stand-in wouldn't work for a Swift type. (And by "wouldn't work" I mean
> "would crash your program".) However, for an Objective-C type, all accesses
> Swift does will always go through the Objective-C runtime, so it's safe to
> use an Objective-C-style proxy, and indeed some Cocoa APIs expect this.
>
> This is probably something we could stand to document more explicitly, but
> I'm not sure where.
>
> Jordan
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160608/e06920b7/attachment.html>


More information about the swift-dev mailing list