timbo
timbo

Reputation: 14334

Why do IBAction types default to AnyObject?

Whenever I create an IBAction I always have to set the default Type (sender) from AnyObject to the only other option which is the actual class type.

Is there a reason for it to always default to AnyObject rather than the object I have explicitly added?

I believe I understand the difference between a UIObject and AnyObject but I fail to see why AnyObject should be the default.

Upvotes: 4

Views: 357

Answers (2)

adrianokw
adrianokw

Reputation: 389

Actually, you can set an IBAction to any class in the hierarchy of that object. If you for example have a class named YellowButton that is a subclass of UIButton, you'll be able to choose between AnyObject, UIButton and YellowButton.

Another thing to consider is that you can have many objects attached to the same IBAction. And they don't even need to be of the same type. For instance, you can have a UIBarButtonItem and a UIButton connected to the same IBAction. You can only do that if the sender type is set to AnyObject.

Now, why Apple chose AnyObject to be the default I can only guess. I think it would be because you can type cast the sender in your method without loosing any information. That way you can even take different actions based on the sender's class.

Upvotes: 4

Bamsworld
Bamsworld

Reputation: 5680

One reason I can think of is let's say I write the interface of an object first but I don't know yet what control type will invoke the action. Or further more I end up with more than one type of control.

By defaulting to AnyObject it fits nicely with objc id type. Also it is scaleable and will work for the general case.

It's also part of Target-Action whereby only certain method signatures must be implemented for it to work.

This extract gives a good scenario -

The senderparameter usually identifies the control sending the action message (although it can be another object substituted by the actual sender). The idea behind this is similar to a return address on a postcard. The target can query the sender for more information if it needs to. If the actual sending object substitutes another object as sender, you should treat that object in the same way. For example, say you have a text field and when the user enters text, the action method nameEntered: is invoked in the target:

- (void)nameEntered:(id) sender {
NSString *name = [sender stringValue];
if (![name isEqualToString:@""]) {
    NSMutableArray *names = [self nameList];
    [names addObject:name];
    [sender setStringValue:@""];
}
}

Here the responding method extracts the contents of the text field, adds the string to an array cached as an instance variable, and clears the field. Other possible queries to the sender would be asking an NSMatrix object for its selected row ([sender selectedRow]), asking an NSButton object for its state ([sender state]), and asking any cell associated with a control for its tag ([[sender cell] tag]), a tag being a numeric identifier

It makes sense to default to id / AnyObject as you can always change it to ensure better type safety.

Upvotes: 4

Related Questions