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

Jordan Rose jordan_rose at apple.com
Wed Jun 8 13:13:52 CDT 2016


> 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/53a67d17/attachment.html>


More information about the swift-dev mailing list