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

时间:2008-11-26 23:15:31

标签: iphone objective-c

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

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

5 个答案:

答案 0 :(得分:238)

来自“Formal Protocols”的Apple页面:

  

任择议定书   方法可以标记为可选   使用@optional关键字。   对应@optional模态   关键字,有一个@required关键字   正式表示的语义   默认行为。您可以使用   @optional和@required进行分区   如你所见,你的协议分为几个部分   适合。如果你没有指定任何   关键字,默认为@required。

@protocol MyProtocol

- (void)requiredMethod;

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

@required
- (void)anotherRequiredMethod;

@end

答案 1 :(得分:29)

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

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

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

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

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

答案 2 :(得分:12)

协议是一套规则。我们可以创建协议,如下例所示:

<强> 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

答案 3 :(得分:11)

在方法声明之前使用@optional关键字使其成为可选项。就这么简单!

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

答案 4 :(得分:4)

协议与抽象类的行为相同,因此@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