views:

344

answers:

3

In Objective-C, I have a category for a class:

@interface UILabel(CustomInit)

- (id)initWithCoder:(NSCoder *)coder;

@end

What I'm doing is writing a custom init function that does some extra stuff, and what I'd like to do, is in this custom init function, call the UILabel's base initWithCoder. Is this possible? How so?

EDIT

Thanks. Ok, so my plans moot. Can't just overload initWithCoder. Is there a way to achieve the same functionality (where all UILabels get this added initialization step) without overloading initWithCoder? Or perhaps is there sample code for the UILabel's initWithCoder that I can just rewrite with the added code?

EDIT

Ok, so to be clear about what I'm trying:

http://stackoverflow.com/questions/360751/can-i-embed-a-custom-font-in-an-iphone-application

has an answer in which someone manually adds a custom font on the iphone using the private GraphicServices function GSFontAddFromFile. I tried this code and it worked great for manually setting the font of a label. However, if you try setting the font in Interface Builder, it doesn't load properly, it just drops down to the system font. What I wanted to do was load the font manually and set the label's font automatically with the chosen font in IB. This way I don't need to make an outlet for every label I put down. I also don't have to write a ridiculous label subclass (which was also suggested in that thread and does a large amount of custom drawing) which I found rather grotesque. Now I could still make a subclass for all my labels, but then there's the case of embedded labels in other UI objects, ie UIButtons. I'd like the embedded labels to also not be broken.

Any suggestions would be great. Thanks.

+10  A: 

From the Mac OS X Reference Library:

When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that already existed in the category's class, there is no way to invoke the original implementation.

Ferruccio
I added some emphasis to your answer, and I'll add here that `initWithCoder:` is certainly implemented by UILabel itself, which means it “already existed in the category's class”.
Peter Hosey
+1  A: 

How do you guys feel about this?

Grab the original method address for initWithCoder at runtime and store it in a static variable. Do a method swizzle on it to replace the classes implementation with the my initWithCoder. And then in my initWithCoder, I would call the original method stored in the static variable.

You can put it in a category and call this class initialization step at the start of the program, making sure it can't be called twice, or if it is it does nothing.

It seems dangerous, but I feel like it should work.

kidnamedlox
Bad idea; dangerous. Good enough for debugging purposes, but don't ship it in production code because, ultimately, it will haunt you.
bbum
What problems do you feel it may cause?
kidnamedlox
+1  A: 

Method swizzling should work as kidnamedlox suggested .

Your exact same question was discussed in this stanford itunes class by Evan Doll

http://deimos3.apple.com/WebObjects/Core.woa/Browse/itunes.stanford.edu.2024353965.02024353968.2173787533?i=1949208242

Surya