Iphone 为什么在Apple';s开发站点为同一类声明三个接口?

Iphone 为什么在Apple';s开发站点为同一类声明三个接口?,iphone,objective-c,ipad,Iphone,Objective C,Ipad,我在尝试掌握Objective-C的同时潜入iOS开发,我仍然处于那个阶段,无论我在哪里看到的东西,对于像我这样的资深C程序员来说都没有任何意义。在中,其中一个头文件声明了一个类接口,三次不同的时间 @interface SessionManager : NSObject <GKSessionDelegate> { NSString *sessionID; GKSession *myGKSession; NSString *currentConfPeerID;

我在尝试掌握Objective-C的同时潜入iOS开发,我仍然处于那个阶段,无论我在哪里看到的东西,对于像我这样的资深C程序员来说都没有任何意义。在中,其中一个头文件声明了一个类接口,三次不同的时间

@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
@接口会话管理器:NSObject{
NSString*sessionID;
GK会议*MYGK会议;
NSString*currentConfPeerID;
NSMutableArray*peerList;
id游说代表;
id游戏代理;
连接状态会话状态;
}
@属性(非原子,只读)NSString*currentConfPeerID;
@属性(非原子,只读)NSMutableArray*peerList;
@属性(非原子,赋值)id lobbyDelegate;
@属性(非原子,赋值)id gameDelegate;
-(无效)会议;
-(void)connect:(NSString*)peerID;
-(BOOL)接受邀请;
-(无效)拒绝邀请;
-(void)sendPacket:(NSData*)类型的数据:(PacketType)类型;
-(void)断开CurrentCall;
-(NSString*)peer的显示名称:(NSString*)peerID;
@结束
//私有方法的类扩展。
@接口会话管理器()
-(BOOL)comparepherid:(NSString*)peerID;
-(BOOL)已启动;
-(无效)voiceChatDidStart;
-(无效)会议;
-(无效)将终止:(NSNotification*)通知;
-(无效)将恢复:(NSNotification*)通知;
@结束
@接口会话管理器(VoiceManager)
-(无效)声音;
@结束
我看到每个接口都不同,但指定相同的类名

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

  • 非常感谢你的智慧

    这些被称为类别,您可以通过类名后的括号看到它们

    他们习惯于将方法分组,而不是将它们全部放在一个大的组中。它们也可以与主类声明分开放置。这在.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
    

    请注意,您不能添加带有类别的实例变量。

    这是出于代码维护的目的,我相信…通过不同的标记接口可以更容易地查看,例如(VoiceManager),它用于VoiceManager设置和与之相关的方法,你有一个处理GK委托方法的接口,以及任何与gamekit的交互……与查看一个巨大的接口文件并选择你要查找的内容不同……它们也可以以这种方式划分实现,以便更容易查看和导航。

    这不是定义接口3次-只有一个接口

    您看到的是向类添加方法的类别

    有一个基本接口来定义属性和一些方法,其中只有一个ant,它定义了对象在内存中的存储方式,是唯一需要的

    目标C在运行时查找方法。这些方法不需要在编译时找到,因此不需要在头/接口等中声明。如果没有声明它们,并且您对它们进行代码调用,那么您将得到编译时警告

    在这种情况下,一个名称为空的类别用于私有函数。我通常只把这个接口放在类的.m文件中,这样其他代码就看不到它,因为它不在头文件中

    第二类是添加使SessionManager满足GKVoiceChatClient协议的方法。这样做的通常原因是将涵盖特定行为的代码分组在一起

    使用类别的另一个原因是向现有类(如NSString)添加方法-您可以创建自己的类别添加方法,而无需像在许多其他OO语言(包括Java和C++)中那样对类进行子类化,顺序如下:

    第一个接口声明是实际的接口声明,它将类声明为NSObject的子类并实现GKSessionElegate协议。它还声明了实例变量和方法的选择

    第二个接口声明是一个类扩展。它可以被认为是一种匿名类别。所以我们现在跳过它,回到它

    第三个接口是类别声明。类别允许您做两件事。它们允许您跨多个源文件拆分类实现。在上面,您将拥有

    @implementation SessionManager
    
    // methods declared in the first @interface
    
    @end
    
    @implementation SessionManager(VoiceManager)
    
    // methods declared in the third @interface
    
    @end
    
    这两个@implementation不需要在同一个源文件中

    类别可以做的另一件事是允许您扩展现有的类<代码>@interface-NSString(MyStringMethods).

    回到类扩展,这有点像匿名类别。其中声明的方法的实现必须在主
    @implement中