Вопрос

Я бы хотел, чтобы объект переменной экземпляра принял протокол.

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

Например, я бы хотел, чтобы мой объект Layer принял <CocosNodeOpacity>, чтобы я мог получить методы

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

бесплатно. Синтаксис, показанный выше, недействителен. Возможно ли достичь этого без создания нового файла реализации и создания пользовательского объекта? Спасибо.

Это было полезно?

Решение

Если это весь код, который вы создали, то лучший способ сделать это, вероятно, заставить сам класс Layer принять протокол, а не переменную.

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

Ключевым преимуществом этого подхода является то, что компилятор проверит, реализовали ли вы все необходимые методы в протоколе во время компиляции, что, как правило, то, что вам нужно. Добавление методов в том же месте, что и в остальной части реализации стандартного класса, проще для понимания (нет необходимости искать источник магического кода) и менее хрупко, чем использование категорий (добавление одного и того же метода через разные категории может привести к неопределенному поведению) , Как правило, я использую категории только тогда, когда у меня есть , например, добавление методов в сторонний код (с закрытым исходным кодом).

Если вы не контролируете источник id, вам, возможно, придется использовать его вместо того, чтобы объявить свой ivar:

Layer<CocosNodeOpacity> *content;

Обратите внимание, что принятие протокола позволяет вам статически печатать переменные с типом класса и получать предупреждения компиляции, если методы отсутствуют. Однако вы не получаете методы & Quot; бесплатно & Quot;, так как вам все равно придется их реализовывать. Тем не менее, разумное использование протоколов и статическая типизация могут сделать ваш код более надежным и & Quot; fail-fast & Quot; чем использовать <=> в качестве типа для всего. Вы должны быть благодарны за то, что вы не просто взяли легкий путь. : -)

Подробнее о протоколах (включая обязательные и необязательные методы) см. в этом ответе SO .

Другие советы

Протокол в Objective-C похож на интерфейс в Java. Протокол определяет набор функций и действует как контракт. Это все равно что сказать & Quot; я гарантирую, что каким бы ни был этот объект, у него есть эти методы. & Quot;

Вы довольно близки к синтаксису в своем первом блоке кода. На самом деле это будет выглядеть примерно так:

@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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top