views:

203

answers:

4

If I have a method that passes an argument of type void * (UIView animation did stop method, has to be a void pointer), or of type id, and I know that the argument is a UIBarButton item, and I need to disable it, [barbuttonitem setEnabled:NO];, should I cast the argument to a UIControl, which is as far as I need to be able to use setEnabled (without a warning), or should I cast it all the way down to UIBarButtonItem? Why?

Thanks!!

+2  A: 

I'd say cast it to a UIControl, just in case the implementation changes at some point. I'd always cast to the most appropriate interface (not implementation), and UIControl is probably the way to go.

Stefan Kendall
Ok, thanks.
Mk12
That's slightly incorrect advice, iftrue. If you are expecting a UIBarButtonItem instance, the most appropriate **interface** is UIBarButtonItem, not UIControl. If you're worried about the implementation changing (which you shouldn't for something like this), you especially cannot trust that it will have the same superclass.
retainCount
Anyone else have an opinion?
Mk12
If you code with UIControl, then you allow you to change from a UIBarButtonItem to something else (e.g. UIButton) and still have all your code work. I wouldn't worry/expect the superclass to change; in any case, all controls are subtypes of UIControl pretty much as a de-facto standard; that will never change.
AlBlue
A: 

Casting is only telling the compiler that you are expecting a variable of a certain type: It does not cause any changes in the variable passed in. You can cast it to UIBarButtonItem without worries.

retainCount
+1  A: 

UIBarItem is not derived from UIControl, so casting to UIControl really isn't the correct thing to do. It works because both classes happen to have setEnabled: methods.

Casts are just another form of documentation; they don't affect what happens at runtime. If you're expecting a UIBarItem then cast it as such.

Darren
Oh, I thought it was a UIControl.
Mk12
A: 

If i understand Objective-C correctly, you can call setEnabled directly on the object; you just won't get a guarantee that the call will go through. But if you know that the object returned is a UIBarItem then you can call it.

RCIX