NSWindow相关方法中sender参数的实际作用是什么?
sender参数的设计本质
这是Cocoa框架Target-Action模式的标准参数设计,最初是为界面交互场景设计:比如菜单栏全屏选项、窗口左上角全屏控件触发toggleFullScreen时,sender就是触发动作的控件实例,方便响应方区分动作的触发来源。
实际场景作用
- 系统原生界面触发动作时,用来识别触发来源,调整对应交互逻辑:比如菜单触发的全屏和按钮触发的全屏,部分系统版本会有细微的动画差异。
- 自定义重写方法时,可以根据
sender的类型、属性执行不同逻辑:比如自己的应用里,从设置页触发的窗口前置要加动画,从主列表触发的不用动画,就可以通过传入不同的sender来做判断。
不同sender值的影响&后续是否被复用
- 系统原生
NSWindow的toggleFullScreen、makeKeyAndOrderFront实现中,不会因为sender不同改变核心执行结果,你手动调用时传nil、self或者任意对象,最终的全屏切换、窗口前置效果都是一致的。 - 系统不会持久化存储你传入的
sender值,方法执行完成后就会释放,没有后续复用逻辑。你提到的windowDidEnterFullScreen通知中无法拿到sender,是因为系统发布通知时没有把该参数加入通知的userInfo字段,原生通知和代理回调默认都不携带该值。
接收方访问sender的方式
只有重写NSWindow的对应方法时,可以直接读取入参的sender值,示例代码如下:
// Swift 实现 class CustomWindow: NSWindow { override func toggleFullScreen(_ sender: Any?) { // 此处可以直接访问sender print("触发全屏的对象:\(sender ?? "无")") super.toggleFullScreen(sender) } override func makeKeyAndOrderFront(_ sender: Any?) { print("触发窗口前置的对象:\(sender ?? "无")") super.makeKeyAndOrderFront(sender) } }
// Objective-C 实现 @implementation CustomWindow - (void)toggleFullScreen:(id)sender { NSLog(@"触发全屏的对象:%@", sender ? sender : @"无"); [super toggleFullScreen:sender]; } - (void)makeKeyAndOrderFront:(id)sender { NSLog(@"触发窗口前置的对象:%@", sender ? sender : @"无"); [super makeKeyAndOrderFront:sender]; } @end
如果需要在代理或者通知回调中拿到sender,需要自己在重写方法时将sender通过关联对象、自定义通知等方式传递到对应位置,原生接口不提供该能力。
实际应用中
sender很难被正确使用,因为需要谨慎保证所有发送者的一致性。消息接收方对sender对象存在特定预期(如类型、可响应的消息),而这些预期无法在类型系统中被明文定义。
内容的提问来源于stack exchange,提问作者CPlus
相关产品推荐
相关产品推荐

