1

Я заметил, что получаю ошибки компиляции, если я помещаю определенные объявления в определенные места в моем заголовочном файле. Я вложил комментарии в код, где я думаю, что некоторые вещи идут; они правильны?Где различные переменные и типы методов должны быть помещены в заголовок

@interface Level : CCNode { 
    //Instance variables? 
    PlayBackgroundLayer* playBGLayer; 
    PlayUILayer* playUILayer; 
    PlayElementLayer* playElementLayer; 
} 

//Static methods? 
+(void) InitLevel: (int) levelNumber; 
+(Level*) GetCurrentLevel; 

//Property declarations for instance variables? 
@property (nonatomic, retain) PlayBackgroundLayer* playBGLayer; 
@end 

//Static variables? 
Level* currentLevel; 
PlayTilemapLayer* playTilemapLayer; 

ответ

1

Вы считаетеся правильным по всем пунктам, кроме одного. Ваши последние переменные не являются статическими переменными, они являются глобальными переменными. Статические переменные - это просто переменные, объявленные с ключевым словом static, и они означают нечто немного отличающееся от других языков. Они не являются переменными класса, они являются переменными, которые видны только файлу, в котором они были объявлены, и только тогда в области, в которой она была объявлена ​​(если вы объявите ее внутри функции, другие функции ее не увидят). Однако, как и следовало ожидать, они объявляются один раз независимо от того, сколько у вас экземпляров. Если вы объявляете что-то вне интерфейса без статического ключевого слова, как и вы, другие классы будут импортировать их. Однако это не идеальный способ выполнить это (вы можете получить ошибки переопределения, если более одного класса импортирует этот заголовок).

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

Наконец, следует отметить, что единственная причина, по которой ваши статические методы методы класса не методы экземпляра происходит потому, что они начинаются с плюс (+) характер, в отличие от минус (-) знак.

+0

Не статические методы, методы класса. –

+0

Я использовал два термина взаимозаменяемо ... не могли бы вы указать на разницу? – borrrden

+0

:) См. Ссылку на сообщение bbum в моем ответе. Примерно, в ObjC нет статических методов - люди просто назовут их, потому что в других языках OO статические методы сортируют заполнение роли, которую методы класса используют в ObjC. Методы класса - это, фактически, методы экземпляра метакласса. –

1

Переменные экземпляра обычно не обязательно должны быть объявлены явно. Они создаются, когда вы используете @synthesize. Если вы хотите, чтобы они, тем не менее, (новый) правильное место * находится в верхней части реализации блока:

@implementation Level 
{ 
    PlayBackgroundLayer* playBGLayer; 
    PlayUILayer* playUILayer; 
    PlayElementLayer* playElementLayer; 
} 

Это не статические методы, they're class methods, но, да, вот где вы объявляете их. Некоторым людям нравится ставить @property объявления до методы класса, но это вопрос мнения. Методы экземпляров идут после обоих из них, хотя технически говоря порядок не имеет значения - то есть компилятору все равно, это просто вопрос удобочитаемости.

Эти переменные верхнего уровня должны идти куда-то, кроме файла заголовка. Если вы поместите их там, вы получите ошибки компиляции, потому что каждый файл, который импортирует заголовок, как представляется, повторно объявляет хранилище для этих переменных, что недопустимо.

Усушно вы помещаете такие переменные в файл .m. Если вы хотите, чтобы они были видны только там, вы использовали бы static. Если вы хотите, чтобы они видны из других файлов, которые импортируют заголовок, вы оставляете static от и объявить переменную extern в заголовке:

extern Level* currentLevel; 

Это позволяет компилятору знать, что для хранения переменной резервируется в другом месте.


* См. "Class Interface" в TOCPL.

+0

Действительно ли это новое правильное место? Я знал об изменениях, но нам рекомендуется помещать их в реализацию, а не в частную категорию интерфейса или интерфейса? – borrrden

+0

@borrrden: Да, см. Ссылку, которую я сделал для TOCPL, особенно «Историческая заметка» в этом разделе. –

+0

У меня была привычка перемещать все мои личные переменные экземпляра в раздел '@interface Foo()' файла .m. Тем не менее, я считаю, что защищенные переменные экземпляра (которые должны быть доступны только для дочерних классов и не подвергаются воздействию свойств) должны по-прежнему поступать в файл заголовка, правильно? – borrrden