ios Difference concepts

Difference between category and extension?

A category is a way to add methods to existing classes. They usually reside in files called “Class+CategoryName.h”, like “NSView+CustomAdditions.h” (and .m, of course).

A class extension is a category, except for 2 main differences:

  1. The category has no name. It is declared like this:

    @interface SomeClass ()
    - (void) anAdditionalMethod;
    @end
  2. The implementation of the extension must be in the main @implementation block of the file.

It’s quite common to see a class extension at the top of a .m file declaring more methods on the class, that are then implemented below in the main @implementation section of the class. This is a way to declare “pseudo-private” methods (pseudo-private in that they’re not really private, just not externally exposed).

share|improve this answer
 
    
Thank you so much. –  Abhinav Aug 17 ’10 at 8:26
8  
In Class-Extensiosn you’re able to overwrite properties from a (public) read-only property to be internally readwrite. And since LLVM 1.5 you’re able to do even more: you can now declare instance variables in a class extension so they are gone from the regular interface.

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?

A: 

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.

 

 

Difference between protocol and delegate

Delegate means passing object from one to another. It passes the message to object when event occurs. Protocols is the list of methods that is shared among classes.

Protocols

Documentation: Protocols

Protocols are interfaces which define certain methods that objects respond to. The key thing about protocols is that they can be adopted by any class, guaranteeing that an object responds to those methods.

If you declare a protocol:

@protocol Photosynthesis
@required
- (void)makeFood:(id<Light>)lightSource;
@optional
+ (NSColor *)color; // usually green
@end

Then you can adopt it from other classes which are not necessarily directly related:

@interface Plant : Eukaryote <Photosynthesis>
// plant methods...
@end
@implementation Plant
// now we must implement -makeFood:, and we may implement +color
@end

or

@interface Cyanobacterium : Bacterium <Photosynthesis>
// cyanobacterium methods...
@end
@implementation Cyanobacterium
// now we must implement -makeFood:, and we may implement +color
@end

Now, elsewhere, we can use any of these classes interchangeably, if we only care about conformance to the protocol:

id<Photosynthesis> thing = getPhotoautotroph(); // can return any object, as long as it conforms to the Photosynthesis protocol
[thing makeFood:[[Planet currentPlanet] sun]]; // this is now legal

Delegates & Notifications

Documentation: Cocoa Design Patterns

These are two ways to pass messages between objects. The main difference:

  • with delegates, one designated object receives a message.
  • any number of objects can receive notifications when they are posted.

Delegates are usually implemented using protocols: a class will usually have something like

@property (weak) id<MyCustomDelegate> delegate;

which gives the delegate a certain set of methods to implement. You can use

myObject.delegate = /* some object conforming to MyCustomDelegate */;

and then the object can send relevant messages to its delegate. For a good common example, see theUITableViewDelegate protocol.

Notifications, on the other hand, are implemented using NSNotificationCenter. An object (or more than one object) simply adds itself as an observer for specific notifications, and then can receive them when they are posted by another object.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(notificationHappened:)
                                             name:MyCustomNotificationName
                                           object:nil];

Then just implement

- (void)notificationHappened:(NSNotification *)notification {
    // do work here
}

And you can post notifications from anywhere using

[[NSNotificationCenter defaultCenter] postNotificationName:MyCustomNotificationName
                                                    object:self
                                                  userInfo:nil];

And make sure to call removeObserver: when you’re done!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s