使用前向声明:@class ViewController;
代替#import "ViewController.h"
。 Objective-C 中的另一个标头中通常不需要导入。
如果你使用ViewController
in GameController
,然后您可以将导入添加到 GameController.m 中。
您可能存在循环依赖。
定义循环依赖的基本方法是:
-
GameController.h
进口ViewController.h
-
ViewController.h
进口GameController.h
首先看到哪一个取决于翻译中声明的顺序,但显然必须先看到一个,因为在这种情况下,标题对于哪个必须先出现存在分歧。
在真实的代码库中,您可以#import "ViewController.h"
在许多源文件中。这会产生非常复杂的依赖关系。这些依赖关系在 ObjC 中基本上是不必要的——大多数时候您可以在标头中使用前向声明(这将缩短您的构建时间)。
所以我解释了最简单的情况,但是当 15 个标头时会发生什么#import ViewController.h
?好吧,您必须追踪哪个标头为该翻译引入了循环依赖关系。如果您不能很好地管理依赖项,那么您可能必须逐步执行数十个(或数百个)文件。有时,最简单的方法是检查该翻译的预处理输出(例如,有问题的翻译)*.m
文件)。如果依赖关系没有最小化,那么输出可能会达到数十万行(如果管理得当,您的构建时间可能会快 20 倍或更多)。因此,在大型代码库中,定位循环依赖关系的复杂性会迅速上升;你越多#import
and #include
在标题中。在标头中使用前向声明(如果可能)可以解决此问题。
Example
因此,鉴于OP中的标题,您可以将其重写为:
游戏控制器.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
游戏控制器.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)应用相同的处理。