2

我想要一个实例变量对象来采用协议。

@interface GameScene : Scene <AVAudioPlayerDelegate> {
@private
    Layer *content <CocosNodeOpacity>;
}

例如,我希望我的 Layer 对象采用,<CocosNodeOpacity>以便我可以获得方法

-(GLubyte) opacity;    //and
-(void) setOpacity: (GLubyte) opacity;

免费。上面显示的语法无效。是否可以在不创建新的实现文件和创建自定义对象的情况下实现这一点?谢谢。

4

2 回答 2

5

如果这些都是您创建的代码,那么最好的方法可能是让Layer类本身采用协议,而不是变量。

@interface Layer : NSObject <CocosNodeOpacity> { ... }

这种方法的一个主要好处是编译器将在编译时检查您是否在协议中实现了所有必需的方法,这通常是您想要的。将方法添加到与标准类实现的其余部分相同的位置更容易理解(无需寻找神奇代码的来源)并且比使用类别更不脆弱(通过不同类别添加相同的方法会导致未定义的行为) . 作为一般规则,我只在必要时使用类别例如向(闭源)第三方代码添加方法。

如果您不控制 的来源Layer,则在声明 ivar 时可能必须使用它:

Layer<CocosNodeOpacity> *content;

请注意,采用协议允许您使用类类型静态键入变量,并在方法不存在时获得编译警告。但是,您不会“免费”获得这些方法,因为您仍然必须实现它们。id尽管如此,明智地使用协议和静态类型可以使您的代码比用作所有内容的类型更健壮和“快速失败” 。你应该受到赞扬,因为你不只是采取了简单的方法。:-)

有关协议(包括必需和可选方法)的一些详细信息,请参阅此 SO answer

于 2009-06-23T21:51:01.710 回答
2

Objective-C 中的协议类似于 Java 中的接口。该协议定义了一组功能并充当合约。这就像说“我保证无论这个对象是什么,它都有这些方法。”

您非常接近第一个代码块中的语法。它实际上看起来像这样:

@interface GameScene : Scene <AVAudioPlayerDelegate> {
@private
    Layer<CocosNodeOpacity> * content;
}

但是,这并不能让您不必在 Layer 类中定义不透明度的方法。使用该协议,您已经确定您的类将具有这些功能,但您实际上并没有提供它们。您仍然需要为它们编写代码。

我认为您正在寻找的是一个 Objective-C 类别。类别提供了一种通过在运行时向其添加方法来扩展任何类的功能的方法。它们是可能的,因为 Objective-C 是一种完全动态的语言。如果您不是 Layer 类的作者,并且不能轻松地向其中添加不透明度方法,那么类别就是要走的路。在某些情况下,类别非常有用——您可以向内置类(如 NSString 和 NSColor)添加方法,而无需现有的类源。

这里有很多关于堆栈溢出的类别文档。苹果文档也很好。这是一篇帮助您入门的文章:

http://macdevelopertips.com/objective-c/objective-c-categories.html

于 2009-06-23T21:46:45.510 回答