Ответ 1
Используйте форвардное объявление: @class ViewController;
вместо #import "ViewController.h"
. Обычно импорт не нужен в другом заголовке в Objective-C.
Если вы используете ViewController
в GameController
, вы можете добавить импорт в GameController.m.
У вас, вероятно, есть круговая зависимость.
Основной способ определения циклической зависимости:
-
GameController.h
importViewController.h
-
ViewController.h
importGameController.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).