Objective-c: Override a method across all sub-classes - objective-c

I want to override the setTitle method of UIViewController across all the sub-classes of UIViewController? I want to customize the title text color of all the views. How can this be done in Objective-C?
Categories is not the recommended way I suppose...

Since you already pointed out that categories are not the recommended way to do this - and the concers in Apple's documentation are valid - an easy and reliable way would be to create a subclass of UIViewController, use it as a kind of template, and then let all your other viewcontrollers inherit from that "template class".

Related

Is it OK to override UIViewController methods on a category on UITableViewController

I know you should not override methods in a category that are defined in the class the category is for. But what about overriding inherited methods. Is that OK?
Specifically, UITableViewController inherits methods like viewWillAppear:, viewWillDisappear, viewDidLoad: and so on, from UIViewController.
So, let's say in a category on UITableViewController, we override those methods inherited from UIViewController.
Is it OK?
As far as I can tell, this will only break if Apple in some future version of UIKit decides to override these methods in UITableViewController.
Are there other reasons not to do this?
EDIT:
So the part about overriding methods in categories in the documentation passed under my radar, so thanks for the answer.
I'll have to solve this with subclassing and possibly extensions.
Overriding methods in a category is discouraged. See Overriding methods using categories in Objective-C
In my opinion it doesn't matter if this means overriding an inherited or class-defined method. Why should it make a difference? Why not subclass?

Delegation coding style?

I have just a minor question about coding style.
I have a subclass of UIViewController which is a delegate to an MKMapView object. Naturally, I have an ivar in my view controller which points to said MKMapView. When I'm writing one of the callback methods mapView:didUpdateUserLocation:, is it smarter to send messages to the passed-in reference of the map view or to the ivar reference of the map view?
I'm aware these are essentially the same thing. I use the ivar reference of the map view object. What are the pros and cons of both styles?
Since you know that both MKMapView objects are one and the same thing, it doesn't matter in this particular case. The reason for the convention requiring the first delegate parameter to be the calling object is to handle the situation when a class is a delegate to more than one object. E.g. if you show two different UIAlertView's in your view controller, and the view controller is a delegate to both (a common scenario), then you want to know in the delegate methods which alert view you're dealing with.

Using a different Superclass, instead of NSObject

This might be a straight forward answer, and I know that you don't have to set NSObject as the Superclass when creating a new class.
But say, for example, I wanted to create a class which held a set of custom CABasicAnimations. Although it may be perfectly ok for me to use CABasicAnimation as the superclass, is it recommended that I follow the unwritten rule and still use NSObject or would you, if you were writing such a class, use CABasicAnimation as the Superclass?
I would assume that it wouldn't matter as long as the Class only contained properties and methods relative to CABasicAnimation.
It would be interesting to here your thoughts!
The rule is to subclass whatever object you are trying to extend. NSObject is used for many subclasses because it is the root object, but if I was going to write a class that was very similar to NSTableView, then I would subclass NSTableView.
In your case, if you are writing a custom animation that you want to call, then you should consider subclassing from CABasicAnimation. On the other hand, if you animation is really just a collection of pre-exisiting CA animations, then NSObject would be fine.
a class which held a set of custom CABasicAnimations.
In this case, I'd like to use Category instead of Subclass.

Why can't new ObjC classes descend from UIViewController?

So, I've been making iOS apps since the first iPod touch came out, but something has always flabbergasted me; why is the list of new Cocoa Touch classes restricted to subclasses of NSObject, UIView, and UITableView? I routinely make subclasses of UIImageView and UIViewController.
Am I "Doing It Wrong™?" Have I totally misunderstood MVC to the point where I make Controller classes where I shouldn't? What is the philosophical reasoning for requiring classes to never descend from a basic controller class?
What gives you the idea that you aren't supposed to subclass UIViewController? This is directly from the documentation for UIViewController:
In a typical iPhone application, there is usually at least one custom subclass of UIViewController and more often there are several.
The C of MVC is supposed to be the least re-usable part it's whole job is to mediate between M & V. If you find something that is in the C section of your code that you have to copy and paste into several subclasses of a given object or into several projects that code should be moved elsewhere.
If you are just basing this off the fact that there is not a nice popup menu item that says UIViewController, don't worry about it Apple has just not bothered to write a template file for that class yet.
Uhm... maybe it's just me, but I see a UIViewController subclass template when I choose new File.
UIViewController template http://files.me.com/aclark78/obnp83
Like #theMikeSwan says, there simply aren't GUI templates for this when you create a new class in Xcode GUI. But you can always create a new subclass whose parent is initially NSObject. After that, you just go to your code and change the parent class to whatever you like.
So... no, you are not doing it wrong in the sense that you rightly understand that often you want to subclass UIViewController; but yes, you are doing it wrong since you assume you shouldn't do this only because Xcode GUI does not support it :)

Objective C protocol as an equal to Java Interface?

The question is not only regarding the headline, but more of a "how will I achieve this, without trying to force a Java/Flash design into an Objective C (iPhone)program".
I have 6 views that extends UIView, these views all have different behavior but share certain methods, like -(void) update and -(void) changeState:(NSInteger)state.
A viewController, whose job is it to update, instantiate and display these views has a switch block to do this. So switch(4) {...} instantiates UIView4, but as I need a reference to the currently instantiated view (to do update and changeState:), I have a UIView property on my ViewController called self.currentView. As the instantiated UIView4 extends UIView I can easily go [self.currentView addSubview:UIView4instance] and then release the UIView4instance.
Now how will I call the [UIView4instance update] method on the view? or the [UIView5instance changeState] etc. etc.
Since I added it to self.currentView which is of type UIView it no longer has any reason to believe it has an update or changeState: method, meaning I cannot iterate the views and send them these messages.
This approach brings on a ton of other problems, I would need to test and typeCast my views each time I needed to do any operations on them.
If I were doing something like this Composite Pattern approach in, say, Java. I would either write an interface that all the views (UIView1, UIview2.... UIViewN) would implement. Or maybe an abstract class that all the views inherited the changeState: and update methods from.
This way I could have self.currentView just know that I'm adding objects to your view and they all conform to these methods.
The two solutions I can think of, with my very small Objective-C experience is:
doing it with delegation or categories, but this seems overkill in every way :/
I guess I could also extend UIView and then extend my class extending UIView again, but there is probably a reason Objective-C does not directly support abstract classes...
Hope someone could point me in the right direction regarding these issues.
Thanks:)
Yes it is equal. You can declare a protocol
#protocol MyViewProtocol
-(void)update;
-(void)changeState:(NSInteger)state;
#end
and declare your subclasses like
#interface MyUIView3 : UIView<MyViewProtocol> {
....
}
....
#end
Then, the declaration
UIView<MyViewProtocol>* view=[[MyUIView3 alloc] init];
means that view is an instance (of a subclass of) UIView which also conforms to MyViewProtocol.
Just the way it works in Java, I think. See the apple doc on protocols.
One thing to be aware of is that while defining a protocol like this is a convenience and certainly makes things clearer, it is by no means necessary to make your solution work. Objective-C binds methods at runtime, and so all you really need to do is to make sure all your view classes implement the methods you care about and call them.
You will get a complier warning for this, but it will work.
Now, in general it's probably preferable to define a protocol like this and it's what I generally do. But it's also important to remember that runtime binding is there and can be incredibly powerful.