[swift-users] Referencing Swift Functions from the Objective-C Runtime
Jacob Bandes-Storch
jtbandes at gmail.com
Mon Nov 21 00:13:52 CST 2016
"throws" is the part that's not representable in Obj-C. Why are you using
it? If you're interacting with method_getImplementation, you need to think
like the Obj-C runtime.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html#//apple_ref/doc/uid/TP40008048-CH104-SW1
This works:
typealias DescriptionMethod = @convention(c) (NSObject, Selector) ->
NSString
let fn =
unsafeBitCast(method_getImplementation(class_getInstanceMethod(NSObject.self,
"description")), DescriptionMethod.self)
fn(NSObject(), "description") as String
Jacob
On Sun, Nov 20, 2016 at 9:41 PM, Jeff Kelley <slaunchaman at gmail.com> wrote:
> Still trying on this (copied the code directly, Foo is actually
> XCTestCase):
>
> typealias TestMethod = @convention(c) (XCTestCase) throws -> Void
>
> This seagulls the compiler with “error: '(XCTestCase) throws -> Void' is
> not representable in Objective-C, so it cannot be used with '@convention(c)
> ’”. I’m trying to use it here:
>
> let testMethod: IMP = method_getImplementation(method)
>
> let test: TestMethod = unsafeBitCast(testMethod,
> to: TestMethod.self)
>
> testMethods.append((methodName as String, test))
>
> If I try to put the type directly in the call to unsafeBitCast(), the
> compiler gives me an error:
>
> Attribute can only be applied to types, not declarations
>
> Thanks for your suggestions! I hadn’t seen @convention() before.
>
>
> Jeff Kelley
>
> SlaunchaMan at gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> |
> jeffkelley.org
>
> On Nov 21, 2016, at 12:08 AM, Jacob Bandes-Storch <jtbandes at gmail.com>
> wrote:
>
> For a function such as bar() above, the type you want to cast the IMP to
> would probably be "@convention(c) (Foo, Selector) -> ()".
>
> On Sun, Nov 20, 2016 at 9:05 PM, Jeff Kelley <slaunchaman at gmail.com>
> wrote:
>
>> Thanks Jacob! I tried using unsafeBitCast, but it fails with the
>> following: “fatal error: can't unsafeBitCast between types of different
>> sizes”. I considered wrapping every call in a closure that calls
>> objc_msgSend(), but alas, that’s not exposed to Swift. I have another
>> approach in mind, so I’ll try that next.
>>
>>
>> Jeff Kelley
>>
>> SlaunchaMan at gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> |
>> jeffkelley.org
>>
>> On Nov 19, 2016, at 1:58 AM, Jacob Bandes-Storch <jtbandes at gmail.com>
>> wrote:
>>
>> I imagine unsafeBitCast would be the way to go here. But are you assuming
>> that all of the instance methods have type "(Foo) throws -> Void" ? Or do
>> you somehow want to dynamically use the type information?
>>
>> Jacob
>>
>> On Fri, Nov 18, 2016 at 10:37 PM, Jeff Kelley via swift-users <
>> swift-users at swift.org> wrote:
>>
>>> Hello,
>>>
>>> I’m trying to enumerate the methods of a class in Swift using the
>>> Objective-C runtime. Everything is working fine so far, except for the very
>>> last step. Suppose I have a Swift class like this:
>>>
>>> class Foo: SomeSuperclass {
>>>
>>> @objc func bar() {
>>> print("Hello, World!")
>>> }
>>>
>>> }
>>>
>>> Using the Objective-C runtime methods, I can get the method with
>>> class_copyMethodList and then get to the method’s implementation using
>>> method_getImplementation. However, what I need to do next is to stick
>>> this into a tuple that looks like this:
>>>
>>> typealias FooEntry = (fooClass: SomeSuperclass.Type, methods: [(String,
>>> (Foo) throws -> Void)])
>>>
>>> For now, the workaround is to make a static variable that returns all of
>>> the entries:
>>>
>>> static var allEntries = {
>>> return [
>>> ("bar", bar),
>>> ]
>>> }
>>>
>>> Is there any way to go from the raw IMP that I get back from the
>>> runtime to the Swift type so I can construct this list dynamically?
>>>
>>>
>>> Jeff Kelley
>>>
>>> SlaunchaMan at gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan>
>>> | jeffkelley.org
>>>
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161120/5cc5e8bd/attachment.html>
More information about the swift-users
mailing list