我注意到在 iPhone SDK 中定义的几个协议中标记为可选的方法,例如 UIActionSheetDelegate协议。
UIActionSheetDelegate
如何定义自己的协议,并将一些方法设置为可选的?
在方法声明之前使用 @optional关键字使其成为可选的。就这么简单!
@optional
// myProtocol.h @protocol myProtocol - (void)myMandatoryMethod:(id)someArgument; @optional - (void)myOptionalMethod:(id)someArgument; @end
// myClass.m @interface myClass : someSuperClass <myProtocol> //... @end
来自“ 正式协议”的苹果页面:
任择议定书 方法可以标记为可选的 使用@可选关键字。 对应于@可选模式 关键字,则有一个“必需的”关键字 正式地表示... 的语义 默认行为。您可以使用 @ 可选且@需要分区 如你所见,将你的协议分成若干部分 如果您没有指定任何 关键字,默认值是@必需的。
@protocol MyProtocol - (void)requiredMethod; @optional - (void)anOptionalMethod; - (void)anotherOptionalMethod; @required - (void)anotherRequiredMethod; @end
协议的作用与抽象类相同,因此@可选关键字定义了那些可选的实现方法。
因此,在代码中,some Method1、 some Method2和 some Method4是必需的方法(必须实现)。Some Method3是可选的-如果我们没有实现这个方法,编译器将不会抛出任何警告。
@protocol myPrtocol<NSObject> -(void)someMethod1:(id)someArgument; -(void)someMethod2:(id)someArugument; @optional -(void)someMethod3:(id)someArgument; @required //by default -(void)someMethod4:(id)someArgument; @end // sampleClass.m @interface sampleClass : someSuperClass <myProtocol> //... @end
如果协议中的某个方法被标记为可选,则必须在尝试调用该方法之前检查对象是否实现了该方法。
例如,饼图视图可以测试段标题方法,如下所示:
NSString *thisSegmentTitle; if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) { thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index]; }
Response sToSelector: 方法使用一个选择器,该选择器引用编译后方法的标识符。您可以使用@selector ()指令并指定方法的名称来提供正确的标识符。
如果此示例中的数据源实现了该方法,则使用标题; 否则,标题保持为空。
协议是一套规则。我们可以创建如下示例的协议:
TestProtocols.h
@protocol TestProtocols <NSObject> @optional -(void)testMethodOptional; @required // by default -(void)testMethodRequired; @end
实施方法:
TestClass.h
#import "TestProtocols.h" @interface TestClass : NSObject <TestProtocols> @end
TestClass.m
#import "TestClass.h" @implemenation TestClass //optional to implement -(void)testMethodOptional{ // Your Code } //required to implement -(void)testMethodRequired{ // Your Code } @end