[swift-users] unsafeBitCast to Unimplemented Class

Saagar Jha saagar at saagarjha.com
Sun Feb 5 00:18:05 CST 2017


Thanks–your not only did you method work, it had the side effect of obviating the need for a Bridging Header. One more thing: what happens if self isn’t a Bar (crash, I’m guessing)? Is there a way to compare the type of self, other than using `is` (which has the same issue as unsafeBitCast in that I don’t have the declaration for it)?

Saagar Jha

> On Feb 4, 2017, at 4:02 PM, Dave Abrahams via swift-users <swift-users at swift.org> wrote:
> 
> 
> on Fri Feb 03 2017, Saagar Jha <swift-users-AT-swift.org <http://swift-users-at-swift.org/>> wrote:
> 
>> Hello,
>> 
>> I’m having an issue migrating some old Objective-C code that looks like this:
>> 
>> @implementation Foo
>> 
>> - (void)load {
>> 	// Swizzle one of Bar’s methods to call Foo’s baz method
>> }
>> 
>> - (void)baz {
>> 	[self baz];
>> 	if ([self isKindOfClass:NSClassFromString(@“Bar”)]) {
>> 		Bar *bar = (Bar *)self; // I can’t migrate this
>> 		// work with bar
>> 	}
>> }
>> 
>> @end
>> 
>> I’m trying to cast self to a Bar at runtime, and use it to call Bar’s methods. Sounds like an easy
>> to task for unsafeBitCast, right? The issue is that I don’t have access to the implementation of
>> Bar’s class at compile time (this is a plugin, so it’s loaded by another application which contains
>> Bar). In Objective-C I can create a header and stick a dummy interface for Bar in it; the cast will
>> work if Bar exists at runtime. However, in Swift, unsafeBitCast requires me to use Bar.self, which
>> does not exist. Is there any way to get this cast to work?
> 
> Bar.self exists if you have a declaration of it exposed to swift, which
> would be required for all the “work with bar” code above.  If you don't
> have Bar.self, it's because there's no declaration visible to your Swift
> code.  My usual workaround would be to declare an @objc protocol having
> the bar APIs you want to use, and then cast self to an instance of that
> @objc protocol.  The right way to do that is by using
> UnsafePointer.withMemoryRebound(to: ), e.g.
> 
>      var mutableSelf = self // can't get pointer to immutable value
>      withUnsafePointer(to: &mutableSelf) { selfPtr in
>        selfPtr.withMemoryRebound(to: BarProtocol, capacity: 1) { barPtr in
>          let bar = barPtr.pointee
>          // work with bar
>        }
>      }
> 
> HTH,
> 
> -- 
> -Dave
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org <mailto:swift-users at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170204/03cc4d9c/attachment.html>


More information about the swift-users mailing list