Нет предупреждения в Xcode в заголовочном файле, включая самого себя

Я включил в свой проект iOS широко используемую категорию UIImage для обработки PDF и получил несколько ошибок компиляции. Это вызвало несколько вопросов.

Q1: Почему Xcode (или компилятор LLVM) не выдает никаких предупреждений о заголовочном файле, который включает сам себя? Я не знаю, имеет ли это особое значение в C или Objective-C, чтобы это не воспринималось как опечатка? В моем примере я считаю, что была допущена ошибка, и Foundation.h, вероятно, предполагалось включить:

В файле категории NSString+MD5.h я нашел:

#import "NSString+MD5.h"

@interface NSString(MD5)
- (NSString *)MD5; 
@end

Соответствующий .m не включает .h. (Ссылка "здесь")

Q2: Я получил ошибку компиляции, потому что я начал с проекта Apple, который НЕ включает платформу Foundation (AVCam 3.1 для iOS)! Итак, NSString не было определено. Я немного озадачен этим, но связывание с базовой структурой в xcode похоже на включение всех его заголовков? Я бы ожидал снова какое-то предупреждение, по крайней мере?

Спасибо за любое объяснение по этой, вероятно, очень простой теме C.


person lazi74    schedule 18.05.2014    source источник
comment
Q2: вы проверили Prefix.pch?   -  person bigblackdot    schedule 19.05.2014
comment
проверьте файл pch, Foundation и uikit импортируются туда для каждого проекта шаблона.   -  person Pawan Rai    schedule 19.05.2014
comment
@bigblackdot и pawan, действительно, Prefix.pch имеет основу и UIKit для большинства проектов (не для AVCam), что объясняет это.   -  person lazi74    schedule 19.05.2014


Ответы (1)


Прежде всего, в Objective-C мы используем #import, что отличается от #include. В то время как #include попытается включить любой файл из списка, #import никогда не будет дважды импортировать какой-либо файл. Я предполагаю, что это объясняет, почему нет проблем с .h файлом, пытающимся #import себя. Неправильно, чтобы файл импортировал себя, но, поскольку это #import, это не вызовет никаких проблем.


Что касается файла .m, который не импортирует файл .h, в данном случае это не обязательно. Это хорошая идея, по привычке всегда импортировать файл .h, и любые файлы, сгенерированные Xcode, будут делать это автоматически, однако это не всегда необходимо. Это необходимо только тогда, когда файл .h объявил что-то, о чем должен знать .m. Например, @property, который вы собираетесь использовать. Вы объявили его в .h, чтобы он имел общий доступ, но если вы собираетесь использовать его в .m, .m должен знать, что @property определено. Кроме того, если вы #importотредактировали некоторые файлы в .h, которые нужны .m, и вы не хотите снова импортировать их в .m, вам придется импортировать .h (хотя, как правило, лучше просто импортировать их в .m.

Здесь .h просто определяет существование метода, который возвращает NSString * и вызывается md5 и не принимает аргументов. Это означает, что все, что импортирует этот файл .h, может вызвать этот метод, и Xcode не будет жаловаться на то, что метод md5 не существует. Соответствующий файл .m реализует метод, который совпадает с тем, который определен в .h. Если вы удалите файл .m, ваша программа почти наверняка все равно скомпилируется нормально... но вы столкнетесь с нераспознанным исключением селектора, когда дойдете до того момента, когда вызывается md5, несмотря на то, что Xcode не жалуется на это. С .m в проекте это исключение не попадает. Программа определяет во время выполнения, какой метод следует выполнить.


И, наконец, что касается исключения Foundation.h, каждый проект iOS, созданный Xcode, имеет #import Foundation.h и #import UIKit.h в предварительно скомпилированном заголовочном файле. Любой другой файл в вашем проекте с этим импортом просто избыточно импортирует файл, поскольку он уже был импортирован .pch, но из-за магии #import (по сравнению с #include) он фактически не импортируется дважды.

Если вы работаете с проектом iOS, в котором нет этих импортов в файле .pch, лучше всего просто вставить их в файл .pch.

Если вы по какой-то причине не согласны с этим, лучший способ исправить этот файл md5 — это простая строка:

@import Foundation.NSString;
person nhgrif    schedule 18.05.2014
comment
Спасибо за объяснение по импорту/включению! И .pch тоже. - person lazi74; 19.05.2014