Learn Objective-C: Day 6

Learn Objective-C: Day 6

Tutorial Details
  • Technology: Objective-C
  • Difficulty: Beginner
  • Completion Time: 20 - 30 Minutes
This entry is part 6 of 6 in the series Learn Objective-C

In today’s tutorial, you will learn about Categories and how to use them to extend the functionality of Cocoa-Touch classes. This is our final installment in the Learn Objective-C series, so you will also be provided with a quick recap on what we’ve covered so far and then look at what you can do to further your skills as an Objective-C or iPhone application developer.

Categories

So, what are categories? A lot of Objective-C tutorials and series will overlook categories, which is a shame as they’re such a useful language feature that’s amazingly useful. Categories help keep code clean and less cluttered by eliminating the need for unnecessary subclassing. From what we’ve learned so far, if we had an NSString object that we wanted to add functionality to do something like add a method that would replace all the ‘a’ characters with a ’4′ (useless I know, but for example purposes only), then we could subclass NSString and add the method ourselves. We also saw this kind of subclassing when we made our car class, I asked you at the end of that tutorial to make a subclass of car so you could add functionality to the base class. Subclassing is a good approach, and I am in no way telling you to stop subclassing, but, in certain situations, categories provide a better approach to add some extra functionality to a class.

Categories allow us to add methods to an existing class, so that all instances of that class in your application gain your functionality. For example, say we have 100 NSString objects in your app, but you’d like to make a custom subclass so each NSString has an extra method (reverseString for example). With categories we can simply add the method in a category and all instances will be allowed to use the new method. The syntax is obviously slightly different from subclassing and categories don’t allow you to use instance variables. However, it is possible to overwrite a method already in place, but this should be done with caution and only if doing so is really necessary.

Syntax

Categories follow the same syntax layout as a class, as in they have an implementation and an interface. The interface looks like this:

@interface ClassNameHere (category)
// method declaration(s)
@end
The implementation looks like this;
@implementation ClassNameHere (category)
// method implementation(s)
@end

Example

Easy, right? So let’s look at an example. We’re going to make a simple method that will reverse a string. While this method is practically useless; it’s not what the method is doing that’s important. You should already know what the interface will look like, but here it is anyway:

@interface NSString (reverse)
-(NSString *) reverseString;
@end

Now to create our implementation:

@implementation NSString (reverse)
-(NSString *)reverseString {
}
@end

Next, we’ll need to add some simple code to flip the string around. Since we’re adding methods to the NSString class, we reference the string using self. Now in order to reverse the string we’ll need a new, temporary string object to hold the reversed string. The way we will reverse the string is to simply loop through the existing string in reverse, each time we find a new character we’ll add it to the reversed string object. The code for this is:

int length = [self length];
NSMutableString *reversedString;
reversedString = [[NSMutableString alloc] initWithCapacity: length];
while (length > 0) {
	[reversedString appendString:[NSString stringWithFormat:@"%C", [self characterAtIndex:--length]]];
}
return [reversedString autorelease];

This method is fairly simple, we’re looping through once for each character in the string. We append the current character using stringWithFormat and the character (C) identifier. When we call –length we not only return the length integer, we also subtract from it too, which is how our loop moves along the string.

If all has gone well then all NSString’s already in our project should adhere to our new category. Now you can see why categories are so useful!

Using Our Example

Ok, now all of our NSString objects should have our reverseString method. Just to recap, our code should look like this:

@interface NSString (reverse)
-(NSString *) reverseString;
@end
@implementation NSString (reverse)
-(NSString *)reverseString {
    int length = [self length];
    NSMutableString *reversedString;
    reversedString = [[NSMutableString alloc] initWithCapacity: length];
    while (length > 0) {
	    [reversedString appendString:[NSString stringWithFormat:@"%C", [self characterAtIndex:--length]]];
    }
    return [reversedString autorelease];
}
@end

Each block of code (interface and implementation) should be in their own respective files by convention. However, we name categories a little differently. The two files we have created are named: NSString+reverse.h (interface) and NSString+reverse.m (implementation).

This is a typical naming convention following the pattern of the name of the class we are adding a category to, a plus sign, and the name of our category. Before we continue, remember that we still need to include our header file into the main project. So now our code should look something like this:

NSString* testString = @"Just a test";
[testString reverseString];
NSLog(@"Reversed: '%@'", testString);

If all went according to plan, then the Console should log a reversed version of “Just a test”!

If all doesn’t go according to plan, check to be sure you’ve copied the code for reverseString properly and make sure you’re including the header (*.h) file for the category in your main code file.

As you can see, categories really are quite useful (especially with strings). They have a wide range of uses in any project, a common one I use is validation. This way I can keep all of my validation in one place and don’t have to use any complicated subclasses.

Wrapping Up The Series

Not only is this the end of todays tutorial, this is the end of the series on the fundamentals of Objective-C. Over the last several tutorials we’ve covered the following topics:

  • Fundamentals of Programming
  • Fundamentals of OOP
  • Classes and Subclasses
  • Memory Management
  • Good Practice
  • Some Standard Naming Conventions

I hope you’ve enjoyed this series, and if you’ve only read one or two of the tutorials so far, then I encourage you to start at day 1 and read a tutorial a day. By the end of the series you should be confident enough to start writing your own code in just under a week!

If you have any questions about the series or examples shown, or if you would like an additional tutorial on another area of Objective-C programming, feel free to leave a comment below.

If you have any questions on Objective-C itself, a project that you’re working on, or just some technical advice, don’t hesitate to drop me a mention or direct message on Twitter or visit my website and find your way to the contact form!

Challenge

Now that we’re finished, the challenges are endless. I highly suggest you put pen to paper and decide on a first app to build from start to scratch. Come up with an idea and a design, then apply all the principles you have learned from this series and let us know what you come up with!

Thanks for reading!

Series Navigation«Learn Objective-C: Day 5

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.amberweinberg.com Amber Weinberg

    I would love it if you’d continue the series, or begin a more intermediate version. I’m getting ready to learn how to use OpenGL to make a drawing app on the iPhone, but what I’ve been dying to learn is how to integrate web interfaces into an app. I’ve been wanting to do a neat iPhone version of Codesnipp.it, and even with everything I’ve learned though Beginning iPhone 3 Development and this series, I still have no clue where to start!

  • David Stenbeck

    Great read, all 6 episodes. Of course there is still much to be discovered and I’d as well really appriciate you continuing this series to the next level.

  • http://www.twitter.com/sswinkels Sebastiaan Swinkels

    Same here, i’m still waiting for more info on pointers and i’d love to see you build a simple iOS or Mac app in a tutorial. Nothing fancy, but with everything you covered explained and used.

  • Andrew Goodlad

    I would also love it if you could carry on. Out of all beginners guides to Objective C this has kept me focused the most and made me begin to understand it.

    So yeah a move to intermediate :D

  • Anton Bramsen

    Yea! i would also say that these tuts has given me some knowledge about the basics of Obj-C. But i wouldn’t say that i could start making my own code from scratch already ! :)

    - I need a little more

  • Cody Anderson

    Thank you for providing this great tutorial Dan. I learned programming in C with the book from Michael Vine so I could make my way into Objective-C but I had a problem with Apple’s online documentation only conceptualizing this great extension of the C language (for starters). This tutorial was streamlined with practical use to enforce those concepts and get a real idea of how to program within Xcode. Want to learn Obj-C? Start here!

  • Lon

    Write a book. You have a clear and concise way of writing that beginners to iPhone development would appreciate. Your short tutorial is much better than most of the iPhone development books I’ve purchased, even though the scope of your writing has been limited in these tutorials. Good work!

  • Anthony

    Thanks for a great series of tutorials Dan!

    I’m in agreement with everyone else here and would love to see you do another series on “Learn Objective-C” to follow on from your tutorials in this series.

    Coming from PHP and Javascript this is all very strange but equally interesting. I’d love to see some more intermediate tutorials, or perhaps a tutorial that focuses on developing an app from start to finish so that we can get a feel for the overall process.

    Thanks again Dan…great series!

  • Marcos Vilela

    Thank you for this Good tutorial!

    Just one question: Why I didn’t see testString reversed? it seems that testString value does not change with reverseString method, instead it returns a new String with reversed value. In order to see the reversed string I used the code below:

    NSString* testString = @”Just a test”;
    NSLog(@”Reversed: ‘%@’”, [testString reverseString]);

    • Allison

      Looks like you need to set the method call to testString to carry the results back into testString.

      testString= [testString reverseString];

  • Nivos

    bro i must say that ur great and thx for 6 good tuts that helped so much .
    anyway how to continue from here ? or some tips what should i learn right now ?

  • SKR

    Dan,
    Thank you for this act of generosity.
    I had one question if you could answer. Please see the lines of code below and the output I get. Is it because NSString is Read-Only or am I missing something obvious?

    NSString *testString = @”Just a test”;

    NSString *xString;

    xString = [testString reverseSttring];

    NSLog(@”Reversed: ‘%@’”, testString);
    NSLog(@”Reversed: ‘%@’”, [testString reverseSttring]);
    NSLog(@”Reversed: ‘%@’”, xString);

    [pool drain];
    return 0;
    }

    2011-05-31 07:35:02.291 Category[223:a0f] Reversed: ‘Just a test’
    2011-05-31 07:35:02.294 Category[223:a0f] Reversed: ‘tset a tsuJ’
    2011-05-31 07:35:02.295 Category[223:a0f] Reversed: ‘tset a tsuJ’

    • http://None Karl

      @SKR

      it’s really quite simple. Xstring is an object added to memory way before you start with your nslogmessages. It is static until you change it, as you created it.

      Think of it as a permanent inverted copy of your test string, but a copy none the less. It is totally unaffected of whatever you do with its initial blueprint “teststring”. You will notice that [Xstring reverseSttring] will give you the sought after response.

      Each time you initialize an object, a block of memory is carved out for it. Both xstring and teststring are objects, xstring made from teststring but their pointers are pointing on two different chunks of memory, hence not affected of change to one another.

      Hope that helped.

    • Saif Idrees

      @SKR

      I think your program is giving normal as expected output.
      The method you wrote “reverseString” takes one String parameter and after reversing just returns an NSString Object.

      Here you passed “testString” and after reversing returns the string to “xString”.
      xString = [testString reverseSttring];

      and here
      NSLog(@”Reversed: ‘%@’”, [testString reverseSttring]);

      after returning reversed string you just print it out directly.

      I hope its clear

    • http://www.facebook.com/sscholle Sebastian Scholle

      NSMutableString *xString;

  • Sharwan

    Its really useful tutorial. I am new to Objective-C and I have learnt the basics of it here. Thanks!

    • http://giggidy.Land.com -_-

      -_-: gigidy, good for you, so you have learned how to create app, great, so far i havent

  • Farhood

    I specially like the way you presented the first series day 1 to day 5. As with day 6 I’m slowly getting confused a little bit but anyway that’s ok because I think that I need more practice. Anyway, I’ll be much appreciated to see further tutorials here.
    Thanks

  • Jun Canonigo

    This tutorial is excellent. Thanks a lot Dan!

  • iTAUMA

    Simply awesome :-) Now I look forward to testing on a Mac. Best wishes. :-)

  • JOSE

    Thanks a lot. This is really jump starter .

  • vvmac

    when the next tutorial will be posted? I can’t wait to learn next one. Anyway, thank you so much!

  • waseem shah

    Hai
    there is all the things are mixed . :-( ur example is so complicated

  • http://part12studios.com zanemx

    Great tutorial! Thanks so much!

  • http://myfacefriends.com Jehnee

    Great!!! Great!!! Thank you so much!!! hoping more like this…

  • innuendoreplay

    Thanks!. With this i was introduced in objective-c :) (previously know c, c++, etc..)

  • Rohan

    Thanks…it was a great read.

  • MagheshBabu

    Simple and powerful nice tutorial for all the beginners who has knowledge on any other programming language

  • Aaron

    I just want to say thank you!

  • http://giggidy.Land.com -_-

    -_-: seriously this tutorial is ment to make me make an app? right now i do not have an ideo of what i can do other than insert data lol and display few text, im trying to make dictionary and i need to insert a file.txt all i do is fail :/ but what ever, nice tutorial thou

    • http://www.danwalker.com/ Dan

      This tutorial isn’t about app making, this series has been about learning to use Objective-C. Someone who goes in to learning app development with an extensive Objective-C knowledge will have a much easier and better time than someone who’s learning everything at once.

  • PZ

    Thanks very much for this.
    Looks like Properties are the way to go.
    What about ARC?

  • Robert

    Thanks for the tutorial. It was a good introduction. I don’t think the last example did what you wanted it to do, but it was a good debugging experience to figure out what it really did, and how it would actually be used.

    It would be useful to see an update that actually goes back and updates the self object with the reversed value, which I think was your original intention, based on the description of the function and the call and expected display.

    Other than this, great job.

    Bob

  • Mel Sovereign

    Many many thanks. This tutorial was perfect for transitioning fromo c++.

  • http://kimuracy007-makinganapplication.blogspot.com/ Cyrus

    Thankyou very much for all these wonderful tutorials you made. I think I will be able to make a simple app now, but I still wish you could continue this series. Still, thank-you for taking me through the Objective C language. If can, I would like to ask you how to make an app that is a calculator. This would be really nice for the school i’m going right now. If can help or email me, please do.
    Thank-you

  • steve mcgarrett

    Mahalo!

  • Francisco

    Thank u very much for this series of tutorials! Helped me to introduce myself to the world of Objective-C, now I spend more time in the deep concepts of language, although with a basic idea

  • Kalyan

    Great work !! definitely a nice place to start Objective C. Thanks for the help !!

  • Daia

    It was really GREAT. Not I have to start working..

  • Neo

    thx for great tutorial!

  • kike

    can anybody suggest me C and C++ is important for the learn objective c???

  • http://securitylearn.wordpress.com satish b

    Highly appreciated your work. I learned very quickly with your tutorials.

  • Gopinath Pandian

    Fruitful Tutorial . Thank you guys.

  • Hitesh

    Thanks for the tutorial. They are great start for me.

  • Antitode

    Thank u so much! It’s so good…..

  • k srinivasareddy

    its a gud platform to learn quicklu gud work guys keep goint…

  • ASHOK KUMAR.P

    ya i read very well. its very much useful for the beginners who learn objective-c . also i need some more tutorials on objective-c. please give me some more topics to learn.

  • http://www.techstarvation.wordpress.com/ Sumit Gupta

    Excellent tutorial series.

  • Sandeep Kumar

    It is realy great for Beginners….

  • nagesh

    Pleae Give some more examples for practice

  • dvd

    it good tutorial for new beginners, but give any brief about objective c or any tutorials

  • Parvezkhan

    Thank it is really helpful for beginners as it helps me..

  • Guest

    Hi! doesn´t works for me, I copy and paste the NSString+reverse (.h and .m) code and the log returns no reverse string. my main file is:

    #import

    #import "NSString+reverse.h"

    int main(int argc, const char * argv[])

    {

    @autoreleasepool {

    NSString *testString = @"Just a test";

    [testString reverseString];

    NSLog(@"Reversed: '%@'", testString);

    }

    return 0;

    }

    • Chandan

      you dont need to import

      #import “NSString+reverse.h”

  • http://www.facebook.com/profile.php?id=100001396315317 Víctor García

    Hi! doesn´t works for me, I copy and paste the NSString+reverse (.h and .m) code and the log returns no revered string, still shows “Just a test”
    What´s wrong?


    #import
    #import "NSString+reverse.h"
    int main(int argc, const char * argv[])
    {
    @autoreleasepool {
    NSString *testString = @"Just a test";
    [testString reverseString];
    NSLog(@"Reversed: '%@'", testString);
    }
    return 0;
    }

    • Ketan Patkar

      NSLog(@”Reversed: ‘%@’”, testString);
      above statement prints the value assigned to the teststring which was “Just a test”

      whereas
      NSLog(@”Reversed: ‘%@’”, [testString reverseString]);

      this statement prints the returned variable from reverseString method which happens to be the reversed string

  • turd

    Great tut, but the last example didn’t work for me – looks like the string ist still being reversed, while it is logged unreversed….but is that even possible..??

    This way it works:

    NSLog(@"Reversed: '%@'", [testString reverseString]);

    This way it doesn’t:

    [testString reverseString]
    NSLog(@"Reversed: '%@'", testString);

    • Ketan Patkar

      This didn’t worked becausea

      NSLog(@”Reversed: ‘%@’”, testString);
      above statement prints the value assigned to the teststring which was “Just a test”

      whereas
      NSLog(@”Reversed: ‘%@’”, [testString reverseString]);

      this statement prints the returned variable from reverseString method which happens to be the reversed string

  • Akiel

    There’s a small mistake in the last snippet of code in the tutorial, which is what’s causing the confusion that many people are having. The -reverseString method as the author has implemented it doesn’t reverse the characters of the string instance it’s called on, rather it creates and returns a new string which is a reversed version of the original string. The original string is unaffected. I’m guessing in the last code snippet the author meant to do:

    NSString* testString = @”Just a test”;

    NSString *reversed = [testString reverseString];

    NSLog(@”Reversed: ‘%@’”, reversed);