Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About performSelector return value

Everyone knows that ios making support for "performSelector" in swift2.0 I want to know how can get the performSelector return value?

let returnValue:Unmanaged<AnyObject> = (self.dataSource?.performSelector("myselector:", withObject: self))!
let value : Int? = returnValue.takeRetainedValue() as? Int

There is a crash at the last line, How can I get the value from "performSelector" in swift2.0?

like image 930
Eric Avatar asked Dec 24 '22 12:12

Eric


2 Answers

I think currently the performSelector in Swift only supports return value conforming to AnyObject, in your case you have Int which does not. In this case, performSelector will return nil, and your code is explicitly unwrapping the Optional making the program crash.

So one way to work around this is to make a method that returns NSNumber.

You can try this code in playground:

@objc class B: NSObject {
  func myselector(arg: A) -> NSNumber {
    return 0
  }
}

@objc class A: NSObject {
  var dataSource: B? = B()
  func a() -> Int {
    let returnValue = self.dataSource?.performSelector("myselector:", withObject: self)
    let value = returnValue?.takeRetainedValue() as! NSNumber
    return value.integerValue
  }
}

A().a()
like image 86
cezheng Avatar answered Feb 16 '23 03:02

cezheng


Use takeUnretainedValue:

let foo = Foo()
let value = foo.performSelector(Selector("bar")) //type of value is Unmanaged<AnyObject?>
let uvalue = value.takeUnretainedValue() //type of uvalue is now AnyObject?
let result = value as? String //type of result is now String

Updated for Swift 5:

also works with NSSelectorFromString: say you have a UIViewController called aViewController.

let value = aViewController.perform(NSSelectorFromString("view")) //type of value is Unmanaged<AnyObject?>
let uvalue = value.takeUnretainedValue() //type of uvalue is now AnyObject?
let myView = value as? UIView //type of result is now UIView
like image 39
spnkr Avatar answered Feb 16 '23 03:02

spnkr