2010-07-28 5 views
8

Tôi bắt đầu phát triển iOS trong khi cố gắng nắm bắt Objective-C và tôi vẫn đang ở giai đoạn đó, nơi tôi nhìn, tôi thấy những thứ không có ý nghĩa với lập trình viên kỳ cựu như tôi. Trong this Game Kit example on Apple's dev site, một trong những tập tin tiêu đề tuyên bố một giao diện lớp, thời gian ba khác nhau ...Tại sao ví dụ mã này trên trang web dev của Apple khai báo ba giao diện cho cùng một lớp?

@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 

tôi thấy rằng mỗi giao diện là khác nhau, nhưng rõ tên cùng lớp.

  1. Lý do cho việc này là gì?
  2. Tôi cũng nhận thấy hành vi tương tự này trong các ví dụ mã khác, chỉ thay vì khai báo nhiều giao diện trong tệp tiêu đề, bạn sẽ thấy một khối @interface được khai báo phía trên cùng của tệp triển khai .m, thường ở trên @implementation block. Tại sao?

Cảm ơn bạn rất nhiều vì đã khôn ngoan!

Trả lời

9

Đây được gọi là Danh mục và bạn có thể xem chúng bằng dấu ngoặc đơn sau tên lớp.

Chúng được sử dụng để nhóm các phương thức thành các khối thay vì có tất cả chúng trong một nhóm lớn. Chúng cũng có thể được đặt riêng biệt với khai báo lớp chính. Điều này đặc biệt hữu ích bên trong các tệp .m, nơi bạn có thể cần phải tạo các phương thức tiện ích cho lớp của bạn, nhưng bạn không muốn chúng hiển thị với các đối tượng khác vì bất kỳ lý do nào (vì vậy bạn không đặt chúng trong .h, được nhập bởi các lớp khác). Một cách sử dụng phổ biến khác là nhóm các phương thức tương ứng với một loại hợp lý nhất định, giao thức không chính thức hoặc những gì có bạn. Danh mục có thể được đặt tên (@interface MyClass (MyCategory)) hoặc ẩn danh (@interface MyClass()). Cái sau thường được sử dụng cho các phương thức riêng tư chung trong tiêu đề của bạn.

(Lý do bạn cần phải loại để khai báo các phương pháp tư nhân trong .m bạn như vậy là trình biên dịch biết về các phương pháp - nếu không, bạn sẽ nhận được một cảnh báo khi bạn cố gắng gọi một phương thức như vậy.)

Cũng , bạn có thể sử dụng các danh mục để thêm các phương thức vào các lớp hiện có. Ví dụ, UIKit chứa một thể loại trên NSString được gọi là NSString (UIStringDrawing). Hoặc nếu bạn muốn tự tạo của riêng mình:

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

Lưu ý rằng bạn không thể thêm biến mẫu với danh mục.

1

Điều này là dành cho các mục đích bảo trì mã tôi tin ... dễ dàng hơn để xem qua các giao diện có nhãn khác nhau, ví dụ (VoiceManager) dành cho thiết lập trình quản lý giọng nói và các phương pháp liên quan đến điều đó, và bạn có một giao diện xử lý các phương thức ủy nhiệm của GK và bất kỳ tương tác nào với bộ công cụ sẽ có ... trái với việc xem một tệp giao diện lớn và phải chọn ra những gì bạn đang tìm kiếm ... Chúng cũng có thể phân chia các triển khai theo cách này để dễ dàng hơn để xem xét và điều hướng.

4

Nó không xác định giao diện 3 lần - chỉ có một giao diện.

những gì bạn đang nhìn thấy là loại mà thêm phương thức cho lớp

Có một giao diện cơ sở đó xác định các thuộc tính và một số phương pháp - có chỉ là một trong những kiến ​​nó định nghĩa như thế nào đối tượng được lưu trữ trong bộ nhớ và là người duy nhất cần thiết.

Mục tiêu C tra cứu các phương pháp tại thời gian chạy. Những phương thức này không cần phải được tìm thấy tại thời gian biên dịch và do đó không cần phải được khai báo trong tiêu đề/giao diện vv. Nếu chúng không được khai báo và bạn mã gọi chúng thì bạn sẽ nhận được cảnh báo thời gian biên dịch.

Trong trường hợp này, một danh mục có tên trống được sử dụng cho các chức năng riêng tư. Tôi thường chỉ đặt giao diện này trong tệp .m của lớp để không hiển thị cho các mã khác không có trong tiêu đề.

Danh mục thứ hai là thêm các phương thức để làm cho SessionManager đáp ứng giao thức GKVoiceChatClient. Lý do thông thường để thực hiện việc này là mã nhóm bao gồm một hành vi cụ thể với nhau.

Một lý do khác cho việc sử dụng loại là thêm phương pháp để một lớp học hiện như NSString -bạn có thể tạo ra loại của riêng bạn thêm các phương pháp mà không cần lớp con của lớp như bạn phải làm trong nhiều ngôn ngữ OO khác bao gồm cả Java và C++

1

Theo thứ tự:

Khai báo giao diện đầu tiên là khai báo giao diện thực tế khai báo lớp là lớp con của NSObject và triển khai giao thức GKSessionDelegate. Nó cũng khai báo các biến cá thể và một phương thức lựa chọn.

Khai báo giao diện thứ hai là một tiện ích mở rộng lớp. Nó có thể được coi là một loại danh mục vô danh. Vì vậy, chúng tôi sẽ bỏ qua nó ngay bây giờ và trở lại với nó.

Giao diện thứ ba là khai báo danh mục. Danh mục cho phép bạn làm hai việc. Chúng cho phép bạn phân chia việc triển khai lớp trên nhiều tệp nguồn. Ở trên, bạn sẽ có

@implementation SessionManager 

// methods declared in the first @interface 

@end 

@implementation SessionManager(VoiceManager) 

// methods declared in the third @interface 

@end 

Hai @thực hiện không cần phải có cùng một tệp nguồn.

Điều khác mà một danh mục có thể làm là cho phép bạn mở rộng các lớp hiện có.e.g. @interface NSString(MyStringMethods)...

Quay lại tiện ích mở rộng lớp học, điều này hơi giống một danh mục ẩn danh. Việc triển khai các phương thức được khai báo trong nó phải nằm trong khối @implementation chính. Mục đích của phần mở rộng lớp là cho phép bạn khai báo riêng API riêng biệt với tệp tiêu đề của lớp. Tôi thường đặt một trong các tập tin.m ở đầu trang nếu tôi có phương pháp chỉ nên được sử dụng từ lớp. Mặc dù, lưu ý rằng đây chỉ là giới hạn thời gian biên dịch. Không có gì để ngăn chặn một tin nhắn mở rộng lớp từ được gửi bởi bất cứ ai tại thời gian chạy.