我正在尝试学习Cocoa,我不确定我是否理解正确...这是关于代表和控制器。
首先:两者有什么区别?有时候,我会看到一个类被称为AppController
的代码,有时候 - 或多或少相同的内容 - AppDelegate
。
因此,如果我理解正确,委托就是一个简单的对象,它会在某个事件发生时接收消息。例如:
@interface WindowController : NSObject <NSWindowDelegate>
@end
@implementation WindowController
- (void)windowDidMiniaturize:(NSNotification *)notification {
NSLog(@"-windowDidMiniaturize");
}
@end
现在,我使用此代码使其成为window
的代表:
@interface TryingAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
@property (assign) IBOutlet NSWindow *window;
@property (retain) WindowController *winController;
@end
通过以下实施:
@implementation TryingAppDelegate
@synthesize window;
@synthesize winController;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSLog(@"-applicationDidFinishLaunching:");
self.winController = [[WindowController alloc] init];
[window setDelegate:winController];
[self.winController release];
}
@end
现在,每当我最小化window
时,它都会向-windowDidMiniaturize:
发送WindowController
条消息。我有这个权利吗?
如果是这样,为什么不直接将NSWindow
作为子类而不是打扰另外一个你需要照顾的课程呢?
答案 0 :(得分:7)
当您希望一个对象协调其他对象时,代理特别有用。例如,您可以创建一个NSWindowController
子类并将其作为窗口的委托。同一窗口可能包含您希望使窗口控制器成为其委托的其他几个元素(如NSTextField
s)。这样您就不需要对窗口及其几个控件进行子类化。您可以将概念上属于的所有代码保存在同一个类中。此外,委托通常属于Model-View-Controller概念的控制器级别。通过继承NSWindow
,您可以将控制器类型代码移动到视图级别。
一个类可以采用任意数量的协议,因此<NSWindowDelegate, NSTextFieldDelegate>
完全有效。然后,您可以将对象设置为任意数量的窗口和文本字段的委托。要查找NSTextField
类支持的委托消息,请查看class reference。-delegate
和-setDelegate:
方法通常会指向正确的协议。在我们的例子中,这是NSTextFieldDelegate
。对于已添加到旧版Apple框架的类,通常会有一个关于委托方法的附加部分(与“类方法”和“实例方法”一起或作为“任务”的子部分)。请注意,将您的类声明为符合委托协议不会将它们神奇地传递给您的对象 - 您必须将其明确设置为委托:
@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
AppController
和AppDelegate
只是同一类型的不同命名约定。