2016-05-09

id Compatibility

Swift includes an AnyObject type that represents some kind of object....

For example, ... you can assign an object of any class type to a constant or variable of AnyObject type. You can also reassign a variable to an object of a different type.

Code:

var myObject: AnyObject = UITableViewCell()
myObject = NSDate()

You can call any Objective-C method and access any property on an AnyObject value without casting to a more specific class type. This includes Objective-C compatible methods and properties marked with the @objc attribute.

Code:

let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow

Because the specific type of an AnyObject value is not known until runtime, it is possible to inadvertently write unsafe code. In Swift as well as Objective-C, attempting to call a method that does not exist triggers an unrecognized selector error.

For example, the following code compiles without a compiler warning, but triggers an error at runtime:

Code:

myObject.characterAtIndex(5)
// crash, myObject doesn't respond to that method

https://developer.apple.com/library/mac ... CAPIs.html

So, for instance, suppose you connect the following action to a UIButton:

Code:

@IBAction func showAnswer (sender : AnyObject) {
sender.characterAtIndex(5)

}

At compile time, Xcode knows that the method characterAtIndex(_:) is a valid method for some iOS object, namely a String, so Xcode does not flag sender.characterAtIndex(5) as an error--because at run time a String might get assigned to the sender parameter variable. However, at run time when you eventually click on the button, and the method showAnswer(_:) is called with a UIButton as the argument, that causes the UIButton to be assigned to the sender parameter variable, which will cause your app to crash when you try to call characterAtIndex(_:) on a UIButton. As a result, using the type AnyObject for the sender parameter variable makes your code more error prone because the compiler cannot detect non-existent methods for the actual type.

If on the other hand, your action looks like this:

Code:

@IBAction func showAnswer (sender : AnyObject) {
sender.gooGooGaGa(5)

}

then Xcode can flag that as an error at compile time--because no iOS class defines a method named gooGooGaGa(_:), therefore no matter what iOS object gets assigned to the sender parameter variable at runtime, the method will be non-existent.

The distinction between compile time and run time is lost on us because we click on one button that both compiles and runs our programs. But if you can image a large app with 20-30 views and hundreds of actions, you may be able to run your app and everything appears to work correctly, and because everything appears to work correctly, you release your app. But soon users start complaining about this button click or that button click crashing your app. Well, if you had written code so that the compiler could have caught those errors, then you would have been able to fix the errors before releasing your app.

Statistics: Posted by 7stud7stud — Mon May 09, 2016 8:41 am

Show more