2011-10-07 15 views
11

Tôi hiện đang cố gắng học Cocoa và tôi không chắc chắn nếu tôi hiểu chính xác ... Đó là về đại biểubộ điều khiển.Đại biểu trong Cocoa là gì và tại sao tôi nên sử dụng chúng?

Lúc đầu: Sự khác nhau giữa hai yếu tố này là gì? Đôi khi tôi thấy mã nơi một lớp được gọi là AppController, đôi khi - với nhiều hoặc ít nội dung giống nhau - AppDelegate.

Vì vậy, nếu tôi hiểu chính xác, đại biểu là một đối tượng đơn giản nhận tin nhắn khi một sự kiện nhất định xảy ra. Ví dụ:

@interface WindowController : NSObject <NSWindowDelegate> 
@end 

@implementation WindowController 
- (void)windowDidMiniaturize:(NSNotification *)notification { 
    NSLog(@"-windowDidMiniaturize"); 
} 
@end 

Bây giờ, tôi sử dụng mã này để làm cho nó một đại biểu của window tôi:

@interface TryingAppDelegate : NSObject <NSApplicationDelegate> { 
    NSWindow *window; 
} 

@property (assign) IBOutlet NSWindow *window; 
@property (retain) WindowController *winController; 

@end 

Với việc thực hiện sau đây:

@implementation TryingAppDelegate 

@synthesize window; 
@synthesize winController; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    NSLog(@"-applicationDidFinishLaunching:"); 

    self.winController = [[WindowController alloc] init]; 
    [window setDelegate:winController]; 

    [self.winController release]; 
} 

@end 

Và bây giờ, mỗi khi tôi giảm thiểu window, nó sẽ gửi một thông báo -windowDidMiniaturize: tới WindowController. Tôi có đúng không?

Nếu vậy, tại sao bạn không chỉ phân lớp NSWindow thay vì làm phiền với một lớp học bổ sung bạn phải chăm sóc?

Trả lời

7

Đại biểu đặc biệt hữu ích khi bạn muốn một đối tượng phối hợp với nhau. Ví dụ: bạn có thể tạo một lớp con NSWindowController và đặt nó làm đại biểu của cửa sổ. Cửa sổ tương tự có thể chứa một số phần tử khác (như NSTextField s) mà bạn muốn làm cho bộ điều khiển cửa sổ là một đại biểu. Bằng cách này bạn không cần phải phân lớp cửa sổ và một số điều khiển của nó. Bạn có thể giữ tất cả các mã mà khái niệm thuộc về nhau trong cùng một lớp. Ngoài ra, các đại biểu thường thuộc về cấp độ bộ điều khiển của khái niệm Model-View-Controller. Bằng cách phân lớp NSWindow, bạn sẽ di chuyển mã loại bộ điều khiển sang cấp chế độ xem.

Một lớp học có thể áp dụng bất kỳ số lượng giao thức nào, vì vậy <NSWindowDelegate, NSTextFieldDelegate> hoàn toàn hợp lệ. Sau đó, bạn có thể đặt đối tượng làm đại biểu của bất kỳ số cửa sổ và trường văn bản nào. Để tìm hiểu xem thông báo nào của một lớp như lớp học NSTextField hỗ trợ xem các phương thức class reference. Các phương pháp -delegate-setDelegate: thường sẽ đưa bạn đến giao thức thích hợp. Trong trường hợp của chúng tôi, đây là NSTextFieldDelegate. Đối với các lớp đã được thêm vào phiên bản cũ hơn của khung công tác của Apple, thường có phần bổ sung về phương pháp đại biểu (cùng với “Phương pháp lớp” và “Phương pháp thể hiện” hoặc dưới dạng phần phụ của “Công việc”). Lưu ý rằng tuyên bố lớp học của bạn như phù hợp với một giao thức đại biểu sẽ không có chúng một cách kỳ diệu giao cho đối tượng của bạn - bạn phải thiết lập một cách rõ ràng như các đại biểu:

@interface MyWindowController : NSWindowController <NSWindowDelegate, NSTextFieldDelegate> { 
    NSTextField *_someTextField; 
} 

@property (nonatomic, retain) IBOutlet NSTextField *someTextField; 

@end 


@implementation MyWindowController 

@synthesize someTextField = _someTextField; 

- (void)dealloc { 
    [_someTextField release]; 
    [super dealloc]; 
} 

- (void)windowDidLoad { 
    [super windowDidLoad]; 
    // When using a XIB/NIB, you can also set the File's Owner as the 
    // delegate of the window and the text field. 
    [[self window] setDelegate:self]; 
    [[self someTextField] setDelegate:self]; 
} 

- (void)windowDidMiniaturize:(NSNotification *)notification { 

} 

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { 
    return YES; 
} 

@end 

AppControllerAppDelegate là quy ước đặt tên chỉ khác nhau cho cùng một loại lớp học.

+0

Cảm ơn bạn! Bộ điều khiển của tôi cần phù hợp với giao thức nào? Tôi đoán khi tôi sử dụng NSWindowDelegateProtocol tôi không thể làm cho nó một đại biểu của một 'NSTextField', phải không? Và tôi nhận được tin nhắn nào từ những yếu tố đó? Vẫn 'windowDidMiniaturize' và vân vân? –

+0

Tôi đã cập nhật câu trả lời của mình để bao gồm một số thông tin về giao thức (đại biểu) và một ví dụ. – gcbrueckmann

Các vấn đề liên quan