I’m diving into iOS development while trying to grasp Objective-C and I’m still in that phase where, ever where I look, I see things that don’t make any sense to a veteran C programmer like myself. In this Game Kit example on Apple’s dev site, one of the header files declares a class interface, three different times…
@interface SessionManager : NSObject <GKSessionDelegate> {
NSString *sessionID;
GKSession *myGKSession;
NSString *currentConfPeerID;
NSMutableArray *peerList;
id lobbyDelegate;
id gameDelegate;
ConnectionState sessionState;
}
@property (nonatomic, readonly) NSString *currentConfPeerID;
@property (nonatomic, readonly) NSMutableArray *peerList;
@property (nonatomic, assign) id lobbyDelegate;
@property (nonatomic, assign) id gameDelegate;
- (void) setupSession;
- (void) connect:(NSString *)peerID;
- (BOOL) didAcceptInvitation;
- (void) didDeclineInvitation;
- (void) sendPacket:(NSData*)data ofType:(PacketType)type;
- (void) disconnectCurrentCall;
- (NSString *) displayNameForPeer:(NSString *)peerID;
@end
// Class extension for private methods.
@interface SessionManager ()
- (BOOL) comparePeerID:(NSString*)peerID;
- (BOOL) isReadyToStart;
- (void) voiceChatDidStart;
- (void) destroySession;
- (void) willTerminate:(NSNotification *)notification;
- (void) willResume:(NSNotification *)notification;
@end
@interface SessionManager (VoiceManager) <GKVoiceChatClient>
- (void) setupVoice;
@end
I see that each interface is different, but specify the same class name.
- What’s the reason for this?
- I’ve also noticed this same behavior in other code examples, only instead of declaring multiple interfaces in the header file, you’ll see an additional @interface block declared towards the top of the .m implementation file, typically above the @implementation block. Why?
Thanks so much in advance for your wisdom!
These are called Categories, and you can see them by the parentheses after the class name.
They’re used to group methods into chunks instead of having them all in one big bunch. They can also be placed separate from the main class declaration. This is particularly useful inside .m files, where you may need to create utility methods for your class, but you don’t want them visible to other objects for any reason (so you don’t put them in the .h, which is imported by the other classes). Another common use is to group methods which correspond to a certain logical category, informal protocol, or what have you. Categories can be named (
@interface MyClass (MyCategory)) or anonymous (@interface MyClass ()). The latter is usually used for generic private methods in your header.(The reason you need categories to declare private methods in your .m is so the compiler knows about the methods — otherwise, you’ll get a warning when you try to call such a method.)
Also, you can use categories to add methods to existing classes. For example, UIKit contains a category on NSString called NSString(UIStringDrawing). Or if you wanted to make your own:
Note that you can’t add instance variables with a category.