Objective-C class extension

class-extensionsobjective c

As a fairly new objective-c programmer (with a 4 years Java experience), I seem to be having a hard time understanding when to use class extensions. From what I understood (and please, correct me if I'm wrong), the main difference between categories and extensions is that the extension expects you to implement the methods inside your main implementation, whereas with a category, it can be in another implementation. It also seems that people are using extensions mainly for private methods.

Here's my first question. What's the difference between using a class extension to declare a private method, and not declare it at all (it seems to compile in run in both cases)? (example 1 vs 2)

Example 1

@interface Class()
-(void) bar;
@end

@implementation Class
-(void) foo {
    [self bar];
}

-(void) bar {
    NSLog(@"bar");
}
@end

Example 2

@implementation Class
-(void) foo {
    [self bar];
}

-(void) bar {
    NSLog(@"bar");
}
@end

Second question: What's the difference between declaring ivars inside the extension and declaring it directly inside the implementation? (Exemple 3 vs 4)

Example 3

@interface Class() {
    NSArray *mySortedArray;
}
@end

@implementation Class
@end

Example 4

@implementation Class
NSArray *mySortedArray;
@end

I have a last question about coding conventions: when should I put an underscore (_) in front of a variable's name?

Thank you

Best Answer

Methods in class extensions

It never used to be the case that you didn't need to declare your private methods. Until recently, you needed to declare your private methods somewhere, and most people chose a class extension to do so. From Xcode 4.4 (I believe), the compiler is clever enough to determine which methods are meant to be private within that implementation, removing the need to declare them elsewhere.

Variables in class extensions

As for examples 3 and 4, be careful. Within a class extension, the variable is an instance variable to that class (example 3). Example 4 declares a global variable (due to the fact it follows global variable semantics from C). Stick with example 3 for your private instance variables.

Coding conventions

As for the coding convention, it's up to the developer/team to decide whether to use an underscore or not. Our team uses m_ for private instance variables. Apple in their documentation suggest using underscores (that's the naming style for the underlying instance variables for synthesized properties). The important thing is, to be consistent throughout your code.