Accessing Method from other Classes Objective-C

Looked for an answer for this question, but I haven't found a suitable one yet. I'm hoping you guys (and gals) can help me out! (This is for an iPhone app)

Alright, I have a Mutliview application. Each view has it's own class, and everything is happy. However, the different classes sometimes call the same method. Up until now, I have simply wrote that Method twice, in both of the class files.

This is what I want to do though:

I want to make a new class, in It's own file, that has all the "Common" Methods. Then, whenever another class needs to call the Method, I simply call it from the other file. This way, when I want to change the Method, I only need to change it in one place, and not all the places...

I'm not sure how I'd do this, which is why I'm asking for help. I'm a little rusty and new for Objective-C, so pretty examples will help me a lot. Allow me to give you one.

File: ViewController1.m

@implementation ViewController1

//Do Some awesome stuff....

CALL "CommonMethod" HERE

@end

File: ViewController2.m

@implementation ViewController2

//Do Some awesome stuff....

CALL "CommonMethod" HERE

@end

File: CommonClass

@implementation commonClass

- (void)CommonMethod:(id)sender
{

//So some awesome generic stuff...



    }
@end

I feel like I need to #import the other file, make an Object from the class and call the Method from the Object... How do I do that?

Thanks again!


Solution 1:

Option 1:

@implementation commonClass
+ (void)CommonMethod:(id)sender  /* note the + sign */
{
//So some awesome generic stuff...
    }
@end

@implementation ViewController2

- (void)do_something... {
    [commonClass CommonMethod];
}


@end

Option 2:

@implementation commonClass
- (void)CommonMethod:(id)sender
{
//So some awesome generic stuff...
    }
@end

@implementation ViewController2

- (void)do_something... {
    commonClass *c=[[commonClass alloc] init];
    [c CommonMethod];
    [c release];
}

@end

Option 3: use inheritance (see Mr. Totland's description in this thread)

@implementation commonClass
- (void)CommonMethod:(id)sender
{
//So some awesome generic stuff...
    }
@end

/* in your .h file */
@interface ViewController2: commonClass

@end

naturally you always need to #import commonClass.h in your view controllers..

Solution 2:

There are some answers here telling you to create a common "parent" class. However I think that you can do a lot better. Create a category for UIViewController instead. You don't know all of the internals of what is going on with UIViewController so I don't think it is worth creating your own View Controller hierarchy off of. In fact it could be dangerous. I ran into a number of problems when I tried to create a "base" UITableViewController and then create classes that inherit from that. I avoided these problems by using categories instead.

Your #1 priority shouldn't be inheriting things for no good reason, it should be getting an app into the app store that people will want to download.

Solution 3:

It sounds to me like the common code doesn't need to be in a class at all. Is there a reason you can't just use a C-style function for what you want to do?

You could put the common code in a class and then make your other two classes subclasses of that one; this method also avoids the code duplication.

Another option might be to write a class method instead of instance methods for this common code. I think most people feel that singletons are best avoided as a design choice.

It would be easier to give a good answer if we knew more about what you were really trying to accomplish.

Solution 4:

What you want to do is to make the two controllers share a common superclass:

UIViewController : MyAwesomeViewController : ViewController1
                                           : ViewController2

commonMethod: would then reside in MyAwesomeViewController. Also, don't start method names with capital letters. :)

To elaborate:

+@interface MyAwesomeController : UIViewController {

-@interface ViewController1 : UIViewController { // and ditto for ViewController2
+@interface ViewController1 : MyAwesomeController {

Solution 5:

Bear in mind that Objective-C is just a superset of C, and that whilst #include directives are mostly used for header files, there's nothing stopping you using a #include to embed the contents of one implementation inside another implementation. If the code is truly identical, you can easily just stick it in its own file, and #include it in the .m file.

Having said that, perhaps it would be better to use this technique in conjunction with categories, especially if the same implementation has similar behaviours.