Friday, January 01, 2016

Swift selector argument - yes you can!

Selectors are an Objective C thing, but sometimes you have to use them in Swift.

For example, if you are calling performSelectorOnMainThread to work around the problem between GCD and UIWebView that causes hangs in stringByEvaluatingJavaScriptFromString (see here) you don't have a choice.

But how to pass an argument? I defined my selector function to take AnyObject? just as I assumed I should since withObject:AnyObject?

So tl;dr - here's what I was doing wrong. The colon at the end of the selector DOES MATTER. Well duh, of course it does, because it indicates there's an argument. Here's an example of everything working correctly...

  private func caller() {
    let arg = 42
    performSelectorOnMainThread("myfunc:", withObject: arg, waitUntilDone: false)
  }

  func myfunc(arg: AnyObject?) {
    guard let n = arg as? Int else {
      print("how did we get in this cornfield?")
      return
    }
    print("and here we are with our arg n: \(n)")
  }

...and the proof of the pudding - my, how tasty!

and here we are with our arg n: 42

I hope this saves somebody else a few hours of struggle!

No comments: