Eyes, JAPAN Blog > Effective Objective-C(2)

Effective Objective-C(2)

will

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

This blog is about some topics about protocol and category.
Objective-C does not have multiple inheritance, so protocols provide a way to define a set of methods that a class should implement. Like interfaces in Java language. Protocols are most often used in implementing the Delegate pattern.
Categories are also important features. They provide a mechanism for adding methods to a class without having to subclass it as you would have to in other language.
1. Some examples protocols in Foundation/UIKit framework
a. NSCopying Protocol
NSCopying declare some methods for a object to copy itself, while the methods need to be implemented by the object.
b. UITableViewDataSource and UITableViewDelegate
The UITableViewDataSource protocol is adopted by an object that mediates the application’s data model for a UITableView object. The data source provides the table-view object with the information it needs to construct and modify a table view.
The delegate of a UITableView object must adopt the UITableViewDelegate protocol. Optional methods of the protocol allow the delegate to manage selections, configure section headings and footers, help to delete and reorder cells, and perform other actions.
2.Use category to break class implementations into manageable segments
Of course you can put all implements of all methods in a single implementation file, but when there are more and more functions or need to refactor it will become difficult to maintain. And categories provide a way to break implementations to several segments.
Give an example of EOCPerson object

#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@property (nonatomic, strong, readonly) NSArray *friends;
- (id)initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName;
/* Friendship methods */
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;
- (BOOL)isFriendsWith:(EOCPerson*)person;
/* Work methods */
- (void)performDaysWork;
- (void)takeVacationFromWork;
/* Play methods */
- (void)goToTheCinema; - (void)goToSportsGame;

You could break these methods into several categories:
EOCPerson+Friendship(.h/.m), EOCPerson+Work(.h/.m), and EOCPerson+Play(.h/.m)
Example of EOCPerson+Friendship(.h/.m):

// EOCPerson+Friendship.h
#import "EOCPerson.h"
@interface EOCPerson (Friendship)
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;
- (BOOL)isFriendsWith:(EOCPerson*)person; @end

// EOCPerson+Friendship.m
#import "EOCPerson+Friendship.h"
@implementation EOCPerson (Friendship)
- (void)addFriend:(EOCPerson*)person {
/* ... */
}
- (void)removeFriend:(EOCPerson*)person {
/* ... */
}
- (BOOL)isFriendsWith:(EOCPerson*)person {
/* ... */
}
@end

3. Use the class-continuation category to hide implementation detail.
The class-continuation category, unlike normal categories, must be defined in the implementation file of the class for which it is a continuation. Unlike other categories, a class-continuation category has no name.
The code like

// EOCClass.h
#import <Foundation/Foundation.h>
@interface EOCClass : NSObject
@end

// EOCClass.m
#import "EOCClass.h"
#import "EOCSuperSecretClass.h"
@interface EOCClass () {
EOCSuperSecretClass *_secretInstance;
}
@end

@implementation EOCClass
// Methods here
@end

4. Avoid Properties in Categories
Although it is technically possible to declare a property in a category, you should avoid doing so if possible. The reason is that it is impossible for a category, except the class-continuation category, to add instance variables to a class. Therefore, it is also impossible for the category to synthesize an instance variable to back the property.

Reference:
<Effective Objective-C 2.0: 52 Specific Ways to Improve Your iOS and OS X Programs> by Matt Galloway

Comments are closed.