【问题标题】:What is a delegate in Cocoa and why should I use them?什么是 Cocoa 中的委托,我为什么要使用它们?
【发布时间】:2011-10-07 10:46:52
【问题描述】:

我目前正在尝试学习 Cocoa,但我不确定我是否理解正确...这是关于 delegatescontrollers

首先:这两者有什么区别?有时我看到一个类被称为 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 时,它都会向WindowController 发送-windowDidMiniaturize: 消息。我有这个权利吗?

如果是这样,你为什么不直接继承 NSWindow 而不是麻烦你必须处理的额外类?

【问题讨论】:

    标签: cocoa delegates


    【解决方案1】:

    当您希望一个对象协调多个其他对象时,委托特别有用。例如,您可以创建一个NSWindowController 子类并使其成为窗口的委托。同一个窗口可能包含您希望将窗口控制器作为其委托的其他几个元素(如NSTextFields)。这样你就不需要子类化窗口和它的几个控件。您可以将概念上属于同一类的所有代码保留在同一个类中。此外,委托通常属于模型-视图-控制器概念的控制器级别。通过继承NSWindow,您可以将控制器类型代码移动到视图级别。

    一个类可以采用任意数量的协议,所以&lt;NSWindowDelegate, NSTextFieldDelegate&gt; 是完全有效的。然后,您可以将您的对象设置为任意数量的窗口和文本字段的代表。要找出像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
    

    AppControllerAppDelegate 只是相同类型类的不同命名约定。

    【讨论】:

    • 谢谢!我的控制器需要遵守什么协议?我想当我使用 NSWindowDelegateProtocol 时,我不能让它成为NSTextField 的代表,对吗?我从这些元素中收到了哪些信息?还是windowDidMiniaturize等等?
    • 我已经更新了我的答案,包括一些关于(委托)协议的信息和一个例子。
    猜你喜欢
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2017-07-28
    • 2010-12-04
    • 1970-01-01
    相关资源
    最近更新 更多