【问题标题】:Why is this delegate method automatically called in Objective-C?为什么这个委托方法会在 Objective-C 中自动调用?
【发布时间】:2016-09-01 23:43:43
【问题描述】:

我正在阅读这本名为“mac os x 的可可编程”的书,我刚从委托开始。与代表的这件事对我来说仍然有点古怪,但我认为我只需要让它解决。

但是有一个练习,我应该实现一个主窗口的委托,这样如果调整大小的高度总是 2xwidth。

所以我得到了 4 个文件:

  • AppDelegate.h
  • AppDelegate.m
  • WindowDelegate.h
  • WindowDelegate.m

AppDelegate 只是您打开一个新的 Cocoa 项目时创建的两个标准文件。我不得不查找解决方案,因为我不太清楚如何完成这项任务。 解决方案就是创建一个新的 cocoa 类“WindowDelegat.h/.m”并将其添加到它的实现文件中:

- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize {
NSSize newSize = frameSize;
newSize.height = newSize.width * 2;
return newSize;
}

然后我打开界面生成器,添加了一个新对象并将其设为我的 WindowDelegate。然后我不得不从 WindowDelegate Ctrl 拖动到实际的窗口,并使其成为窗口的委托。 单击运行,它工作。耶!但为什么? 首先,我认为“windowWillResize”只是这些回调函数之一,一旦调整窗口大小就会被调用,但事实并非如此。通常方法被调用是因为程序的一般生命周期调用它们或者因为它们是@IBAction、按钮或不同的控制元素。 但是“windowWillResize”不是其中之一。那为什么叫它呢?

编辑:问题解决了!非常感谢!

现在我正在尝试以编程方式将代理连接到窗口。因此,我将 WindowDelegate 中的引用出口删除到界面生成器中的实际窗口。它有效,但我只是想验证它是否以正确的方式完成:

AppDelegate.h

#import <Cocoa/Cocoa.h>
#import "WindowDelegate.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>

@end

AppDelegate.m

#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (strong) WindowDelegate *winDeleg;

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

- (void)awakeFromNib {
    [_window setOpaque:NO];
    NSColor *transparentColor = [NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:0.5];
    [_window setBackgroundColor:transparentColor];
    NSSize initialSize = NSMakeSize(100, 200);
    [_window setContentSize:initialSize];

    _winDeleg = [[WindowDelegate alloc] init];
    [_window setDelegate: _winDeleg];
}
@end

WindowDelegate.h

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

@interface WindowDelegate : NSObject <NSWindowDelegate>

@end

WindowDelegate.m

#import "WindowDelegate.h"

@implementation WindowDelegate

- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize {
    NSSize newSize = frameSize;
    newSize.height = newSize.width * 2;
    return newSize;
}

- (id)init {
    self = [super init];
    return self;
}
@end

为什么WindowDelegate 的@property 需要强? 我的 winDeleg 不是一个对象吗?当它是一个对象时,为什么我必须通过 _winDeleg 访问它。我虽然下划线是用来访问变量的?

感谢您的帮助!

【问题讨论】:

    标签: objective-c macos cocoa delegates


    【解决方案1】:

    点击运行,它工作。耶!但为什么呢?

    因为NSWindow 的实例有一个delegate 属性,该属性可以指向任何实现NSWindowDelegate 协议的对象,并且该协议包括-windowWillResize:toSize: 方法。

    多读几遍。这很重要的原因是您可以创建自己的对象,例如实现NSWindowDelegate、实现-windowWillResize:toSize:,并将该对象设置为窗口的委托。然后,每当用户调整窗口大小时,都会调用您的方法并可以修改建议的新大小。

    通常调用方法是因为程序的一般生命周期会调用它们,或者因为它们是@IBAction、按钮或不同的控制元素。但是“windowWillResize”不是其中之一。那为什么叫它呢?

    这真的没什么不同。将委托视为“辅助对象”。它们允许您自定义对象的行为,而无需创建全新的子类。 NSWindowDelegate 对象本质上是NSWindow 承诺遵循的契约:无论何时发生某些事情,例如用户调整窗口大小,如果委托存在并实现这些方法,窗口将调用其委托对象中的某些方法.在NSApplication 的情况下,许多委托方法是应用程序生命周期事件,例如应用程序启动或退出或从操作系统获取消息。在NSWindow 的情况下,委托方法对应于可能发生在窗口上的有趣事件,例如用户移动它、隐藏它、显示它、最大化它、将它移动到不同的屏幕等。其他类,如文本视图或网络连接或电影播放器​​,有自己的一组有趣的事件和自己的委托协议来匹配。

    请注意,标记为IBAction 的方法实际上不是委托方法,它们只是被对象调用的方法,例如使用目标/动作范例的控件。 IBAction 关键字让 IDE 知道它应该将哪些方法呈现为按钮等可能的操作。您经常在窗口控制器和视图控制器中找到操作,并且这些对象经常充当其他对象的委托,但操作本身并不是委托协议的一部分。例如,NSTableView 采用一个委托对象,该对象确定表的行为方式以及其中显示的内容。将管理表的视图控制器作为表的委托通常是有意义的,并且同一个视图控制器可能还管理一些按钮并包含所述按钮触发的操作方法,但这些操作不是NSTableViewDelegate 的一部分协议,因此您不会称它们为delegate methods.

    【讨论】:

    • 好的!通过 ctrl 从对象拖动到界面生成器中的窗口,我会自动将委托属性设置为我创建的 WindowDelegate。通过这样做,“:NSObject ”协议也被添加到我的WindowDelegate类中?因为我看不到它,但它确实有效。
    • 没错。您定义了一个类 (WindowDelegate),然后创建了该类的一个实例并将其设为窗口的委托。
    • 协议只定义了一个接口,一个对象必须或可能实现的方法列表。 (协议中的方法可以是可选的或必需的。)您可以检查一个对象是否符合协议(每个对象都有一个-conformsToProtocol: 方法)以及它是否实现了给定的方法(-respondsToSelector:)。您通常不关心委托对象是什么类型,您只关心它实现了哪些方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多