web-dev-qa-db-ja.com

目的C-エラー:「タイプが必要です」

単純だと思っていたもので、非常に奇妙なエラーが発生しました。

#import <Foundation/Foundation.h>
#import "ViewController.h"
#import "GameObject.h"


@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

「ViewController」がタイプであるかどうかを疑問視するのはなぜですか?これは私が正しく実装したクラスです。それも輸入されています。

編集*

役立つ場合は、ViewController.mクラスを次に示します。

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[GameController sharedGameController] initializeGame:self];
}

@end

編集2 **​​

およびViewController.hファイル

#import <GLKit/GLKit.h>
#import "GameController.h" 

@interface ViewController : GLKViewController

@end
17
user2577959

前方宣言を使用します:@class ViewController; 代わりに #import "ViewController.h"。 Objective-Cの別のヘッダーでは、インポートは通常不要です。

ViewControllerGameControllerを使用する場合、インポートを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をインポートしています)に適用できます。

43
justin

ViewController.h内で定義されたクラスインターフェイスのスペルも "ViewController"であることを確認しますか?

プロジェクトでViewController.hクラスを作成して簡単なテストを行いましたが、その内部でインターフェースの名前をViewControllersに変更すると、同じエラーが発生しました。

0
Sid