为什么Apple的开发站点上的这个代码示例为同一个类声明了三个接口?

Bea*_*red 8 iphone objective-c ipad

我在尝试掌握Objective-C时正在深入iOS开发,我仍然处于那个阶段,在我看来,我看到的东西对像我这样的资深C程序员来说没有任何意义.在Apple的开发站点上的这个Game Kit示例中,其中一个头文件声明了一个类接口,三次不同...

@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
Run Code Online (Sandbox Code Playgroud)

我看到每个接口都不同,但指定了相同的类名.

  1. 这是什么原因?
  2. 我在其他代码示例中也注意到了这种相同的行为,只是在头文件中声明了多个接口,而不是在.m实现文件的顶部声明了一个额外的@interface块,通常在@implementation块之上. .为什么?

非常感谢您的智慧!

jtb*_*des 9

这些被称为类别,您可以在类名后面的括号中看到它们.

他们习惯于将方法组合成块而不是将它们全部放在一大堆中.它们也可以与主类声明分开放置.这在.m文件中特别有用,您可能需要为您的类创建实用程序方法,但是您不希望它们因任何原因对其他对象可见(因此您不要将它们放在.h中,这是由其他类导入).另一个常见用途是对与某个逻辑类别,非正式协议或您拥有的内容相对应的方法进行分组.类别可以命名为(@interface MyClass (MyCategory))或匿名(@interface MyClass ()).后者通常用于标头中的通用私有方法.

(你需要类别在.m中声明私有方法的原因是编译器知道方法 - 否则,当你尝试调用这样的方法时会收到警告.)

此外,您可以使用类别向现有类添加方法.例如,UIKit在NSString上包含一个名为NSString(UIStringDrawing)的类别.或者,如果你想自己做:

@interface NSString (MyFoo)
+ (NSString *)fooString;
@end
//... somewhere else...
@implementation NSString (MyFoo)
+ (NSString *)fooString { return @"foo!"; }
@end
Run Code Online (Sandbox Code Playgroud)

请注意,您无法使用类别添加实例变量.