Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call IMP in Swift?

Tags:

ios

swift

Since Swift2 you can use good ole':

class_getMethodImplementation(cls: AnyClass!, _ name: Selector) -> IMP

It returns imp. In Objective-C you just call it like:

implementation(self, selector)

But how to call it in Swift?

like image 833
orkenstein Avatar asked Sep 09 '15 12:09

orkenstein


2 Answers

Based on the article Instance Methods are Curried Functions in Swift it's pretty easy to achieve the desired result:

typealias MyCFunction = @convention(c) (AnyObject, Selector) -> Void
let curriedImplementation = unsafeBitCast(implementation, MyCFunction.self)
curriedImplementation(self, selector)
like image 160
Fabio Poloni Avatar answered Nov 16 '22 00:11

Fabio Poloni


I was trying to get runtime calls working on an instance method with parameter(s). @Fabio's answer got me most of the way there. Here's a full example for future googlers:

import Foundation

class X {
  @objc func sayHiTo(name: String) {
    print("Hello \(name)!")
  }
}

let obj = X()
let sel = #selector(obj.sayHiTo)
let meth = class_getInstanceMethod(object_getClass(obj), sel)
let imp = method_getImplementation(meth)

typealias ClosureType = @convention(c) (AnyObject, Selector, String) -> Void
let sayHiTo : ClosureType = unsafeBitCast(imp, ClosureType.self)
sayHiTo(obj, sel, "Fabio")
// prints "Hello Fabio!"
like image 9
Lou Zell Avatar answered Nov 16 '22 01:11

Lou Zell