什么是Cocoa中的委托,我为什么要使用它们?

11 cocoa delegates

我正在尝试学习Cocoa,我不确定我是否理解正确...这是关于代表控制器.

起初:两者有什么区别?有时我会看到调用类的代码AppController,有时候 - 或多或少相同的内容 - AppDelegate.

因此,如果我理解正确,委托就是一个简单的对象,它在某个事件发生时接收消息.例如:

@interface WindowController : NSObject <NSWindowDelegate>
@end

@implementation WindowController
- (void)windowDidMiniaturize:(NSNotification *)notification {
    NSLog(@"-windowDidMiniaturize");
}
@end
Run Code Online (Sandbox Code Playgroud)

现在,我使用此代码使其成为我的代表window:

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

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

@end
Run Code Online (Sandbox Code Playgroud)

通过以下实现:

@implementation TryingAppDelegate

@synthesize window;
@synthesize winController;

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

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

    [self.winController release];
}

@end
Run Code Online (Sandbox Code Playgroud)

现在,每当我最小化时window,它都会向我发送-windowDidMiniaturize:消息WindowController.我有这个权利吗?

如果是这样,为什么你不是只是继承NSWindow而不是打扰你需要照顾的额外课程?

gcb*_*ann 7

当您希望一个对象协调其他对象时,代理特别有用.例如,您可以创建一个NSWindowController子类并将其作为窗口的委托.同一窗口可能包含NSTextField您希望使窗口控制器成为委托的其他几个元素(如s).这样您就不需要对窗口及其几个控件进行子类化.您可以将概念上属于的所有代码保存在同一个类中.此外,委托通常属于Model-View-Controller概念的控制器级别.通过子类化,NSWindow您可以将控制器类型代码移动到视图级别.

一个类可以采用任意数量的协议,因此<NSWindowDelegate, NSTextFieldDelegate>是完全有效的.然后,您可以将对象设置为任意数量的窗口和文本字段的委托.为了找出委托的消息像一类的NSTextField支座检查出类的引用 .The -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
Run Code Online (Sandbox Code Playgroud)

AppController并且AppDelegate只是同一类型的不同命名约定.