Make Your Life Easier With Reusable Code

If you have spent any amount of time learning or working with the iPhone SDK then you are probably getting frustrated with the very wordy (and difficult to remember) nature of the Cocoa framework.  Things that are trivial in environments like .NET or Java can seem awkward and clumsy in Cocoa.

As an example of this wordiness, here is what I do to create a button in code:

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectZero;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
;
 forState:UIControlStateNormal];
button.backgroundColor = [UIColor clearColor];
button.frame = CGRectMake(10, 10, 100, 50);
;

And here is what I routinely do to use a simple alert box (one line of code in .NET):

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Help Message"
                                                message:message
                                               delegate:self
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles: nil];
[alert show];
[alert release];

To be fair, every programming language has issues like this to some extent and the purpose of this post is not to bash Cocoa.  The purpose of this post is to suggest a way to make your life easier by learning how to reuse your code.

WARNING: There is a 50% chance that what I am about to suggest will deeply offend you!

There are a few different ways to make your code reusable – in object-oriented programming whole books have been written about this.  What I am about to tell may offend both object-oriented purists as well as people who truly love the way Cocoa does things.

My suggestion is to simply pay attention to the code that you are writing over and over again;  then put this code into static functions in a class that you can simply call from any other classes.  Programming veterans will be familiar with this approach (and might as well skip to the code examples at this point).

So, if you put all that wordy code into a static function you can use that code in the future with only one line required to get the same behavior.  This makes your code more readable and will decrease your time coding because you are not re-doing the same thing over and over again.

WHY WOULD SOMETHING SO COOL OFFEND PEOPLE?

This approach is basically creating global functions and sort of steps on the toes of good object-oriented design that insists that objects created from a class that have all the information and behavior required to get by in your program.  Intermixing global functions doesn’t quite fit into this and could lead to the problem of “spaghetti code” if you are not careful or if you are excessive in this approach.

Other people simply believe that the Cocoa way is the best way and that essentially creating your own framework on top of Cocoa some form of denial system.   Like most system design choices there are +/- and you will have to keep your thinking cap on.

HERE IS WHAT I DO

Personally, I use static functions to help me work with using the log since I hate using the NSString stringWithFormat nonsense.  I also use it for alerts and buttons.  In general, I try to keep the global static functions to very general things and keep anything else in the class where it belongs.  For example, all database access functions I put into a SQLite object that just accesses data.

NSLOG EXAMPLE

I use NSLog a lot while debugging code and even though it only requires one line of code I find it awkward to use.  So, I have created three static functions to automate this for me:

+(void) logThis:(NSString *) message;
+(void) logThis:(NSString *) message andThisFloat:(float) number;
+(void) logThis:(NSString *) message andThisObject:(id) object;

This makes it easy to shoot out a message to the log – either by itself, with number value (very common need) or the string value of any object.

Here I will show you the steps required to create these static functions so that you can do for yourself in the future.

First, open up your favorite XCode project and add a NSObject subclass file.  You will have two files (one with a h file extension and one with a m file extension).  You will need to edit both.

Open the header file (with the h!) and add this code:

#import
@interface ASFunctions : NSObject {
}

+(void) logThis:(NSString *) message;
+(void) logThis:(NSString *) message andThisFloat:(float) number;
+(void) logThis:(NSString *) message andThisObject:(id) object;

@end

Now, add this code to the implementation file (m):

+(void) logThis:(NSString *) message{
     NSLog(message);
}

+(void) logThis:(NSString *) message andThisFloat:(float) number{
     NSLog([NSString stringWithFormat:@"%@ = %f", message, number]);
}

+(void) logThis:(NSString *) message andThisObject:(id) object{
     NSLog([NSString stringWithFormat:@"%@ = %@", message, object]);
}

Put this after the @implementation but before the @end.  Ok, almost done.  In order to use this from another part of the program you must add some code to the file you are working with.  For instance, I am going to add these functions to my app delegate for simplicity.  Add the reference to the header file to the top:

#import "ASFunctions.h"

Now all you need to do is simply call the functions as you need them. Since they are static you do not need to worry about allocating the object. Here is how to use the simplest log function I wrote:

[ASFunctions logThis:@"Writin' to da log!"];

Using the other functions is similar:

[ASFunctions logThis:@"Writin' to da log!" andThisFloat:4];

Well, that is it. These examples are almost too simple for this approach but I hope they give you some ideas about the code you would like to put into static functions.

What do YOU think?  What functions make sense to be put into global static functions?  What don’t?  Should everything be object-oriented or what?

Comment below!

7 Responses to Make Your Life Easier With Reusable Code

  1. iPhoneKicks.com March 3, 2009 at 6:17 pm #

    Make Your Life Easier With Reusable Code…

    You’ve been kicked (a good thing) – Trackback from iPhoneKicks.com – iPhone SDK links, community driven…

  2. bpenrod March 11, 2009 at 1:57 am #

    I’ve been enjoying the blog. Thanks for sharing!
    I agree that Cocoa is often pretty verbose but as for NSLog, you can actually write things like:
    NSLog(@”Logging an object: %@”, myObject);
    very much like printf() with addition of the %@ specifier which will print the object’s description (you can write your own – (NSString*) description method to return a custom string, just like Java’s toString() method!

  3. mattjdrake March 11, 2009 at 11:35 am #

    @bpenrod – thanks for pointing that out. That will help me out a lot when using NSLog.

    So, the method you override is “-(NSString *) description”? That is pretty cool.

  4. pgor March 12, 2009 at 2:48 pm #

    Has anybody actually expressed offense at this yet? Based on your examples, you’re just wrapping already static functions (because they’re plain C) or already class-level methods into class-level utility methods. I see nothing wrong with this–Apple already does it in so many of their frameworks–as long as it doesn’t eventually lead to being overly dependent on shoehorning all your calls into “simplified” methods. Your thinking for the logThis methods is great to have for a consistent log format in your app.

    I’d recommend cleaning up your logThis methods, though. As @bpenrod points out, NSLog already behaves similarly to printf. First, you are creating a temporary NSString with stringWithFormat: that just adds overhead to reproduce NSLog’s formatting functionality; NSLog is already overhead enough without another temp object.

    Second, calling NSLog with only a single parameter (as all your calls end up) can be dangerous. If either ‘message’ or ‘object’ contain a ‘%’ character, NSLog will try to interpolate the next parameter on the stack–which is undefined. Making your methods ‘NSLog(@”%@”,message,nil)’, ‘NSLog(@”%@ = %f”, message, number,nil)’ and ‘NSLog(@”%@ = %@”, message, object,nil)’ respectively should clean this up. (The nil isn’t necessary, I’m just paranoid and like the parallels with NSArray and NSDictionary methods.)

    Wow, that got verbose for what’s really just a touch of polish. Keep up the good work.

  5. The Code that Picked the Conte May 18, 2009 at 1:39 pm #

    [...] over again I have created a function to use an alert with one line of code. A while back I wrote an article about why and how I do this if you are interested check it out [...]

  6. The Code that Picked the Conte May 18, 2009 at 1:43 pm #

    [...] over again I have created a function to use an alert with one line of code. A while back I wrote an article about why and how I do this if you are interested check it out [...]

  7. Reading and Writing Text Files June 24, 2009 at 2:02 pm #

    [...]       //use simple alert from my library (see previous post for details)       [ASFunctions alert:content];       [...]

Leave a Reply

Switch to our mobile site