Используйте предварительное объявление: @class ViewController;
вместо #import "ViewController.h"
. Импорт обычно не нужен в другом заголовке в Objective-C.
Если вы используете ViewController
в GameController
, то вы можете добавить импорт в GameController.m.
Возможно, у вас круговая зависимость.
Основной способ определения циклической зависимости:
GameController.h
импортирует ViewController.h
ViewController.h
импортирует GameController.h
Какой из них будет отображаться первым, зависит от порядка объявления в переводе, но, очевидно, один из них должен стоять первым, потому что в этом случае заголовки расходятся во мнениях относительно того, какой из них должен стоять первым.
В реальной кодовой базе вы можете #import "ViewController.h"
использовать многие исходные файлы. Это создает очень сложные зависимости. Эти зависимости в значительной степени не нужны в ObjC — вы можете использовать предварительные объявления большую часть времени в заголовке (и это сократит время сборки).
Итак, я объяснил простейший случай, но что происходит, когда 15 заголовков #import ViewController.h
? Что ж, вам нужно будет отследить, какой заголовок вводит эту циклическую зависимость для этого перевода. Если вы плохо управляете зависимостями, вам, возможно, придется просмотреть десятки (или сотни) файлов. Иногда проще просто просмотреть предварительно обработанный вывод для этого перевода (например, оскорбительный файл *.m
). Если зависимости не сведены к минимуму, этот вывод может состоять из сотен тысяч строк (и время сборки может быть в 20 или более раз быстрее, если им правильно управлять). Таким образом, сложность обнаружения циклических зависимостей быстро возрастает в больших кодовых базах; тем больше у вас #import
и #include
в заголовках. Использование предварительных объявлений в заголовках (где это возможно) решает эту проблему.
Пример
Итак, учитывая ваш заголовок в OP, вы можете переписать его как:
GameController.h
// includes
#import <Foundation/Foundation.h>
// forwards required by this header
@class GameObject;
@class GLKBaseEffect;
@class ViewController;
// header declarations
@interface GameController : NSObject
@property (strong) GLKBaseEffect * effect;
@property (strong) NSMutableArray * gameObjects;
@property (strong) NSMutableArray * objectsToRemove;
@property (strong) NSMutableArray * objectsToAdd;
+ (GameController *) sharedGameController;
- (void) tick:(float)dt;
- (void) initializeGame: (ViewController*) viewcontroller;//ERROR: EXPECTED A TYPE
- (void) createObject:(Class) objecttype atPoint:(CGPoint)position;
- (void) deleteObject:(GameObject*) object atPoint:(CGPoint)position;
- (void) manageObjects;
@end
GameController.m
#import "GameController.h"
#import "ViewController.h" // << if you need it in this source
#import "GameObject.h" // << if you need it in this source
@implementation GameController
...
Затем вы можете применить ту же обработку к ViewController.h (который импортирует GameController.h).
person
justin
schedule
12.07.2013
ViewController
? - person Wain   schedule 13.07.2013@class ViewController;
над @interface - person Grady Player   schedule 13.07.2013#import "ViewController.h"
Нет необходимости в предварительном объявлении. - person David Rönnqvist   schedule 13.07.2013