Reputation: 14334
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
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
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