关于@protocol的含义及NSView类遵循协议的技术问询
在Objective-C里,@protocol就是用来定义协议的核心关键字,你可以把协议理解成一套“行为契约”——它会列出一组方法声明,有的是必须实现的,有的是可选的,任何类只要声明遵循这个协议,就可以选择(或必须)实现这些方法,从而拥有协议规定的行为能力。
举个接地气的例子:假设我们要定义所有动物都该有的基本行为,就可以写个协议:
@protocol Animal <NSObject> // 默认是必选方法,也可以用@required明确标记 - (void)makeSound; @optional // 可选方法,类可以按需实现 - (void)run; @end
然后让Dog类遵循这个协议:
@interface Dog : NSObject <Animal> @end @implementation Dog - (void)makeSound { NSLog(@"汪汪汪"); } // run方法我们可以选择不实现,因为它是可选的 @end
协议最常用的场景就是实现代理模式(比如iOS里的UITableViewDelegate、macOS里的NSWindowDelegate),或者让不同类拥有统一的行为接口,方便做多态处理——比如不管是Dog还是Cat,只要遵循Animal协议,我们都可以调用makeSound方法,不用管具体是哪个类。
先给你拆解一下你看到的代码:@protocol NSDraggingSource; 这只是一个前向声明,意思是“告诉编译器这个协议存在,后面我再给你看具体内容”,通常用来避免循环引用的编译问题,不代表NSView不遵循它。
从你贴的@interface NSView : NSResponder <..., NSDraggingDestination,...> 能看到NSDraggingDestination是它明确遵循的协议之一,但作为macOS AppKit里的基础视图类,NSView还遵循不少其他协议,我整理了主要的几个:
NSDraggingDestination:处理拖放操作中“接受拖入内容”的逻辑,比如判断能不能接受拖进来的数据,以及拖入后的处理NSDraggingSource:没错,虽然你看到的是前向声明,但NSView本身也遵循这个协议,它既可以作为拖放的“源”(把视图里的内容拖出去),也可以作为“目标”NSCoding:支持对象的归档和解档,比如把视图的状态保存到文件,或者从文件恢复NSCopying:允许创建视图的拷贝对象NSUserInterfaceValidations:用来验证用户界面元素(比如菜单按钮)是否可用,比如某些操作只有在特定状态下才能触发NSAccessibility&NSAccessibilityElement:支持无障碍功能,让屏幕阅读器等辅助设备能识别和操作视图
另外,因为NSView继承自NSResponder,NSResponder本身遵循的NSUserInterfaceValidations协议,也会被NSView继承下来。
内容的提问来源于stack exchange,提问作者Bob Ueland

