Casting Anyone to AnyObject in Swift

I have an object contained in a dictionary, for example:

let dict:<String, Any> = ["obj": self]

      

Then later I try to use this object as the target of the button:

button.addTarget(dict["obj"], action: "buttonPress:", forControlEvents: .TouchUpInside)

      

And I am getting the error:

Type '(String, Any)' does not conform to protocol 'AnyObject'

      

I guess my problem here is to use Any

both AnyObject

. Is it possible?

+3


source to share


3 answers


Disconnecting from Any

to is AnyObject

not possible, and yes, the problem you have is about Any

not converting to AnyObject

.

Any

can represent any type (classes, structures, enumerations, ints, strings, etc.), whereas AnyObject

can only represent reference types (i.e. classes).

To solve the problem, I think you should change the dictionary to store values ​​like AnyObject

:

let dict:<String, AnyObject> = ["obj": self]

      

Note that even if a dictionary contains values AnyObject

, it can also store:



  • numbers
  • strings
  • arrays
  • dictionaries

because these types are automatically connected to the respective types objc ( NSNumber

, NSArray

, NSDictionary

etc.)

If you really want the most flexibility, I suggest using NSDictionary

, but in this case, the value types should be explicitly labeled in reference types (i.e. int

in NSNumber

, etc.).

Also @rintaro answers in another good variation.

+3


source


Any

before AnyObject

. You can expand Any

to AnyObject

using .unsafelyUnwrapped

of Any

no matter what classes, structs, enums, ints, strings, etc.

Here it _change[.oldKey]

returns Any

, expands and discards it on AnyObject

, as is done in the code below.



 override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        guard let oldKey = (_change[.oldKey].unsafelyUnwrapped as AnyObject).cgPointValue else {
                        return
                    }
        guard let newKey = (_change[.newKey].unsafelyUnwrapped as AnyObject).cgPointValue else {
                        return
                    }
        print(oldKey)
        print(newKey)
    }  
extension NSKeyValueChangeKey {
    public static let newKey: NSKeyValueChangeKey
    public static let oldKey: NSKeyValueChangeKey
}

      

I used KVO ObserveValue forKeyPath

to get the format changes [NSKeyValueChangeKey : Any]

.
I have successfully retrieved the CGPoint

values ​​converted from Any

to AnyObject

, then to CGPoint

.

+3


source


You can not throw Any

up AnyObject

, but may transfer it to any particular class:

    button.addTarget(dict["obj"] as UIViewController, action: "buttonPress:", forControlEvents: .TouchUpInside)

      

Of course this can lead to a runtime error if dict["obj"]

not UIViewController

, so make it more secure:

    if let target = dict["obj"] as? UIViewController {
        button.addTarget(target, action: "buttonPress:", forControlEvents: .TouchUpInside)
    }
    else {
        fatalError("dict[\"obj\"] is not UIViewController!")
    }

      

And of course it's better to use your own subclass instead of UIViewController

.

+2


source







All Articles