Почему @class вместо #import для ViewController в AppDelegate.h?

У меня есть основной вопрос с наилучшими практиками в Objective C. Я понимаю разницу между @class и #import, но я не понимаю, почему шаблоны Apple Xcode по умолчанию делают это:

AppDelegate.h:

@class ViewController;

.m:

#import "ViewController.h

Если бы вместо этого просто поместить последний #import в .h и оставить упоминание ViewController из .m в целом, тем самым упростившись на 1 строку кода.

Конечно, сохранение 1 строки кода не является проблемой, мне просто интересно, почему так делается?

Ответ 1

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

Представьте себе файл a.h, который делает #import "b.h". Теперь каждый файл, который импортирует a.h автоматически, также импортирует b.h, что увеличивает объем работы, которую должен выполнить компилятор. С помощью форвардных объявлений часто можно избежать такого дополнительного импорта и тем самым избежать дополнительной работы для компилятора.

Чем больше проект и чем сложнее иерархии классов и зависимости, тем более эти #import могут стать проблемой. Поэтому неплохо разработать привычку использовать передовые декларации, где это возможно.

Изменить: После комментариев появился другой важный прецедент: для разрешения циклических зависимостей. Например, если класс A хочет ссылаться на класс B и наоборот, нужно определить его перед другим. Но поскольку они должны знать, что у нас есть парадокс. Он решил вот так:

// Tell the compiler: B will be a class type.
@class B;

// Now we can define A, the compiler has enough
// information to know what B means.
@interface A : NSObject {
    B *b;
}
@end

// Since A is now defined, we can define B.
// Cycle is resolved.
@interface B : NSObject {
    A *a;
}
@end

Ответ 2

Объявление прямого класса:

@class ClassName;

Используется в файлах заголовков, где не требуется специфицировать свойства, атрибуты или методы.

Это позволяет #import или #include файла заголовка без каких-либо издержек, связанных с #import ing ClassName.h.

Ответ 3

#import используется для класса, который предопределен нами или Apple xcode, но @class мы используем, прежде чем мы его определим (это прямое объявление класса), в нашем родительском/предыдущем классе

поэтому он сообщает компилятору, что в нашем проекте есть класс с этим именем, поэтому компилятор не помещает ошибки для этого имени класса.