如何使用可选方法创建协议?


133

我注意到在iPhone SDK中定义的几种协议中标记为可选的方法,例如该UIActionSheetDelegate协议。

如何定义自己的协议,并将一些方法设置为可选方法?

Answers:


248

在Apple页面上的“ 正式协议 ”中:

可以使用@optional关键字将可选协议方法标记为可选。对应于@optional模态关键字,有一个@required关键字正式表示默认行为的语义。您可以使用@optional和@required将协议划分为合适的部分。如果未指定任何关键字,则默认值为@required。

@protocol MyProtocol

- (void)requiredMethod;

@optional
- (void)anOptionalMethod;
- (void)anotherOptionalMethod;

@required
- (void)anotherRequiredMethod;

@end

4
注意:'''@optional'''和'''@required'''指令适用于其后的所有方法。
韦恩

31

如果协议中的方法被标记为可选,则在尝试调用该对象之前,必须检查对象是否实现了该方法。

例如,饼图视图可能会测试段标题方法,如下所示:

NSString *thisSegmentTitle;
if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {
    thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}

respondsToSelector:方法使用选择器,该选择器引用编译后方法的标识符。您可以使用@selector()指令并指定方法的名称来提供正确的标识符。

如果此示例中的数据源实现了该方法,则使用标题;否则,将使用标题。否则,标题保持为零。


7
确保在协议中扩展NSObject以使用
responsToSelector

1
对,就像@protocol MyProtocol <NSObject>
劳伦斯·凯斯特洛特

这是一个完美的答案!
smoothdvd

14

协议是一组规则。我们可以按照以下示例创建协议:

测试协议

@protocol TestProtocols <NSObject>
    @optional
    -(void)testMethodOptional;

    @required  // by default
    -(void)testMethodRequired;
@end

实现方式:

测试类

#import "TestProtocols.h"
@interface TestClass : NSObject  <TestProtocols>

@end

测试类

#import "TestClass.h"
@implemenation TestClass
    //optional to implement 
    -(void)testMethodOptional{
     // Your Code
    }

    //required to implement 
    -(void)testMethodRequired{
     // Your Code
    }
@end

12

@optional在方法声明之前使用关键字将其设置为可选。就那么简单!

// myProtocol.h
@protocol myProtocol
- (void)myMandatoryMethod:(id)someArgument;
@optional
- (void)myOptionalMethod:(id)someArgument;
@end
// myClass.m
@interface myClass : someSuperClass <myProtocol>
    //...
@end

6

协议的作用与抽象类相同,因此@optional关键字定义了对于实现而言是可选的那些方法。

因此,在代码中,someMethod1,someMethod2和someMethod4是必需的方法(必须实现)。someMethod3是可选的-如果我们未实现此方法,则编译器将不会引发任何警告。

@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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.