Подтвердить что ты не робот

Какая разница между #import и @class, и когда я должен использовать один над другим?

Я учил себя Objective-C за последний месяц или около того (я - глава Java), и теперь у меня есть мозг вокруг большей части его. Одна вещь, которая меня путала в данный момент: Какая разница между импортом класса через @class и выполнением #import?

Это лучше, чем другой, или мне нужно использовать один вместо другого в определенных случаях? До сих пор я использовал только #import.

4b9b3361

Ответ 1

#import выводит весь заголовочный файл в текущий файл; все файлы, в которые включен файл #import. @class, с другой стороны (при использовании в отдельной строке с некоторыми именами классов), просто сообщает компилятору "Эй, скоро вы увидите новый токен, это класс, так что относитесь к нему так).

Это очень полезно, когда у вас есть потенциал для "круговых включений"; т.е. Object1.h ссылается на Object2, а Object2.h ссылается на Object1. Если вы #import оба файла в другом, компилятор может запутаться, когда он пытается #import Object1.h, смотрит в него и видит Object2.h; он пытается #import Object2.h и видит Object1.h и т.д.

Если, с другой стороны, каждый из этих файлов имеет @class Object1; или @class Object2;, тогда нет круговой ссылки. Просто убедитесь, что на самом деле #import требуемые заголовки в ваших файлах реализации (.m).

Ответ 2

@class называется форвардным объявлением. Вы в основном говорите компилятору, что класс существует, но не что-то вроде класса. Таким образом, он не знает таких вещей, как его суперкласс и какие методы он декларирует.

Как правило, используйте @class в .h и #import в .m, если это вообще возможно. Как сказал Луис, это поможет ускорить время компиляции. Однако есть моменты, когда вам нужно #import класс в заголовке. Случаи, о которых я сейчас думаю, следующие:

  • Вы подклассифицируете другой класс
  • Вы реализуете протокол

В этих случаях вы должны #import заголовочный файл, где объявлен класс или протокол, потому что компилятор должен знать полную иерархию классов своих родительских классов и протоколы реализации.

FWIW, вы также можете перенаправлять протоколы объявлений, пока вы их не выполняете:

@protocol SomeProtocol;

@interface ...

- (id<SomeProtocol>)someMethod;

@end

Ответ 3

Другая вещь, которую вы хотите иметь в виду, - это то, что #imports замедляет время компиляции, поскольку это означает, что компилятору нужно тянуть и работать с гораздо большим количеством файлов заголовков. Это в основном маскируется использованием предварительно скомпилированных заголовков, но мне иногда дают проекты, которые корс импортировал каждый заголовок, а не при необходимости, используя @class, и исправление их может улучшить время компиляции. Это тонкий путь, который система усиливает тот факт, что если вы используете только то, что вам действительно нужно, дела идут быстрее.

Как правило, я всегда использую объявления @class в своих заголовочных файлах и только #import суперкласс. Это согласуется с предложениями Бена, но я думал, что стоит отметить, что даже если вас не беспокоят круговые ссылки, это хорошая идея ограничить #imports в файлах заголовков, если вы можете.