on Sat Feb 04 2017, Saagar Jha <saagar-AT-saagarjha.com> wrote: > Thanks–your not only did you method work, it had the side effect of > obviating the need for a Bridging Header.
Uh, wait: this doesn't add up. If you needed a bridging header before, surely it was so that you could get a declaration for Bar? If that's the case, you shouldn't be using this protocol hack. > One more thing: what happens if self isn’t a Bar (crash, I’m > guessing)? No, it should just be using ObjC method dispatch (a.k.a. duck-typing) under the covers. If you have a method with the right signature, things just work. > 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)? I think you might be able to use something like class_getName(type(of: x)) > > Saagar Jha > >> On Feb 4, 2017, at 4:02 PM, Dave Abrahams via swift-users >> <[email protected]> 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 >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-users > <https://lists.swift.org/mailman/listinfo/swift-users> -- -Dave _______________________________________________ swift-users mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-users
