类别与非正式协议

use*_*739 4 iphone protocols objective-c categories

我想我理解(正式)协议和类别之间的区别.现在,如果我做对了,非正式协议应该是类别(通常在NSObject上定义),这些类别用于某些目的(可能只提供实现其中列出的部分方法的机会,与正式协议不同).我需要确定一下:任何人都可以确认非正式协议只是一个类别(或解释差异)吗?谢谢.

Mic*_*ler 8

Category是类功能的扩展 - 这是一些方法的实现:

@interface NSObject (MyCategory)
  - (void)doSomething;
@end

...

@implementation NSObject (MyCategory)
  - (void)doSomething {
    // do something...
  }
@end
Run Code Online (Sandbox Code Playgroud)

正式协议是完全不同的.如果您熟悉其他一些面向对象的语言,那么它就像接口(在Java,C++,C#等).
协议可以附加到任何类实现,如下所示:

@protocol MyProtocol
@required
- (void)doSomething;
@optional
- (void)doSomethingOptional;
@end

...

@interface MyClass : NSObject <MyProtocol> {
}
@end

...

@implementation MyClass
  - (void)doSomething {
    // do something...
  }
@end
Run Code Online (Sandbox Code Playgroud)

根据文档,非正式协议是NSObject类的类别(我从未使用过这种方法):

@interface NSObject (MyInformalProtocol)
- (void)doSomething;
@end

...

@implementation NSObject (MyInformalProtocol)
  - (void)doSomething {
    // do something...
  }
@end
Run Code Online (Sandbox Code Playgroud)


小智 5

非正式协议确实只是在NSObject上定义的类别,但是如果你定义了一个委托接口,那么有一种更好的方法.相反,使用可选方法的正式协议(即实际的,实际的@protocol定义).这允许您在编译时测试委托的类型(即它实际上符合协议),如果您使用了错误的对象,则会收到警告.

@protocol GLFunkyObjectDelegate
@optional
-(void)funkyObject: (GLFunkyObject *)obj willDoSomething: (GLSomeThing *)thing;
-(void)funkyObject: (GLFunkyObject *)obj didDoSomething: (GLSomeThing *)thing;
@end

@interface GLFunkyObject {
  id <GLFunkyObjectDelegate> delegate;
}
//...
@end
Run Code Online (Sandbox Code Playgroud)