12

Otrzymuję bardzo dziwny błąd na czymś, co uważam za proste.Cel C - Błąd: "Oczekiwano typu"

#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 

Dlaczego miałby pytanie, czy "ViewController" jest typem? Jest to klasa, którą poprawnie zaimplementowałem. Został również zaimportowany.

EDIT *

Oto klasa ViewController.m czy to pomaga.

#import "ViewController.h" 

@implementation ViewController 

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

@end 

EDIT 2 **

i ViewController.h złożyć

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

@interface ViewController : GLKViewController 

@end 
+2

Jak definiuje się "ViewController"? – Wain

+0

To może ci pomóc, podobne pytanie: http://stackoverflow.com/a/9607607/1422070 – edwardmp

+0

Może wewnątrz pliku .h źle wpisałeś nazwę klasy. –

Odpowiedz

34

Użyj do przodu deklarację: @class ViewController; zamiast #import "ViewController.h". Import jest zwykle niepotrzebny w innym nagłówku w Objective-C.

Jeśli używasz ViewController w GameController, możesz dodać import do GameController.m.

Prawdopodobnie masz zależność cykliczną.

Podstawowym sposobem definiowania kołową zależność jest:

  • GameController.h import ViewController.h
  • ViewController.h import GameController.h

Który z nich będzie można zobaczyć pierwszy zależy od kolejności deklaracji w tłumaczenie, ale oczywiście trzeba będzie przyjść jako pierwszy, ponieważ w tym przypadku nagłówki nie zgadzają się co do tego, która musi być pierwsza.

W prawdziwym codebase możesz #import "ViewController.h" w wielu plikach źródłowych. Tworzy to bardzo złożone zależności. Zależności te są w dużej mierze niepotrzebne w ObjC - możesz używać zgłoszeń forward w większości przypadków w nagłówku (i poprawi to czas budowania).

Wyjaśniłem najprostszy przypadek, ale co się dzieje, gdy 15 nagłówków #import ViewController.h? Cóż, musiałbyś wyśledzić, który nagłówek wprowadza zależność cykliczną dla tego tłumaczenia. Jeśli nie zarządzasz dobrze zależnościami, możesz przejść przez dziesiątki (lub setki) plików. Czasami najłatwiej jest przejrzeć przetworzone dane wyjściowe dla tego tłumaczenia (np. Obraźliwy plik *.m). Jeśli zależności nie zostaną zminimalizowane, dane wyjściowe mogą być setkami tysięcy linii (a czasy kompilacji mogą być 20 lub więcej razy szybsze, jeśli zostaną poprawnie zarządzane). Tak więc złożoność lokalizowania zależności cyklicznych szybko rośnie w dużych bazach kodu; im więcej jesteś #import i #include w nagłówkach. Używanie zgłoszeń do przodu w nagłówkach (jeśli to możliwe) rozwiązuje ten problem.

Przykład

Więc biorąc pod uwagę twój nagłówek w PO, można przepisać jako:

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 
... 

Następnie możesz zastosować to samo traktowanie ViewController.h (który importuje GameController.h).

+0

Zawarłem deklarację forward i zaimportowałem nagłówek do pliku ".m". Wciąż dostaję ten sam błąd. Czy możesz wyjaśnić nieco więcej kwestii "zależnej zależności"? – user2577959

+0

Mój projekt ma tę zależność cykliczną. Jak mam to poprawić? – user2577959

+0

@ user2577959 zaktualizowano na przykład – justin

0

Czy jesteś pewien, że interfejs klasy zdefiniowany wewnątrz ViewController.h jest również zapisany jako "ViewController"?

Zrobiłem szybki test, tworząc w moim projekcie klasę ViewController.h, ale zmieniono nazwę interfejsu na ViewControllers w środku i otrzymałem ten sam błąd co ty.

+0

Wystarczy dwukrotnie sprawdzić. Wszystko jest napisane poprawnie – user2577959

+0

Czy możesz zamieścić deklaracje dla ViewController? – Sid