【问题标题】:Categories vs Informal Protocols类别与非正式协议
【发布时间】:2010-02-02 10:52:44
【问题描述】:

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

【问题讨论】:

标签: iphone objective-c protocols categories


【解决方案1】:

类别是类功能的扩展——这是一些方法的实现:

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

...

@implementation NSObject (MyCategory)
  - (void)doSomething {
    // do something...
  }
@end

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

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

...

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

...

@implementation MyClass
  - (void)doSomething {
    // do something...
  }
@end

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

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

...

@implementation NSObject (MyInformalProtocol)
  - (void)doSomething {
    // do something...
  }
@end

【讨论】:

    【解决方案2】:

    非正式协议确实只是在 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
    

    【讨论】:

      【解决方案3】:

      The Objective-C Manual 说你是对的 - 非正式协议通常是类别。

      除了正式协议之外,您还可以通过将方法分组在类别声明中来定义非正式协议:

      但是,您可以通过口口相传来实现一个非正式协议——当然,在为接口构建器实现委托方法时,我从来没有想过要寻找一个类别;除了非正式协议之外,类别也用于other things

      【讨论】:

        【解决方案4】:

        协议只是接口的定义。

        一个类别(针对 NSObject)既是一个接口的定义,也是该接口的一个实现,所有子类(NSObject 的)都将继承,除非它们覆盖了该类别的方法。

        虽然 Apple 过去选择通过针对 NSObject 创建类别来定义非正式协议,但这并不意味着一个就是另一个的定义。

        您可以通过声明接口但不实际实现它来半定义一个类别,这应该(在公正和公平的世界中)导致编译错误发生,因为 Objective-C 编译器肯定会抱怨“不完整的实现” ' 用于真实接口。但是他们已经被滥用了足够长的时间,以至于你可以期望他们的行为不会改变。

        【讨论】:

          猜你喜欢
          • 2011-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-29
          相关资源
          最近更新 更多