Objective-C 头文件无法将自定义对象识别为类型

标签 objective-c import compiler-errors

我正在使用 cocos2d 开发一款适用于 iPad 的游戏,该游戏涉及一个装有不同类型瓷砖的棋盘。我创建了一个名为 Tile 的自定义类作为图 block 的通用模板,并创建了一些 Tile 的子类,它们具有不同的属性和方法。我还创建了一个名为 Board 的类,除其他外,它使用特殊坐标系跟踪所有图 block 的位置。

出于某种原因,在 Board 类中,编译器似乎没有将 Tile 识别为一种对象,即使我已经添加了 #import "Tile.h" 在文件的顶部。

相关代码如下(请问是否还有你想看的代码的其他部分):

Tile.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Board.h"

@interface Tile : NSObject

-(void) updateNeighbors;

@property (nonatomic, retain) CCSprite* sprite;
@property (assign) CGPoint coords;
@property (assign) CGPoint positionInPoints;
@property (nonatomic, retain) NSMutableArray *neighbors;

@end

Board.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Tile.h"

@interface Board : NSObject

+(Board*)sharedBoard;

- (void) putTile: (Tile*) tile AtIndex: (CGPoint) index; //<-- error here!
- (void) replaceTileAtIndex: (CGPoint) index1 WithTileAtIndex: (CGPoint) index2;
- (Tile*) tileAtIndex: (CGPoint) index; //<-- error here!
- (void) populate;

@property (nonatomic, retain) NSMutableArray *tiles;
@property (nonatomic, retain) NSString *type;
@property (assign) CGPoint size;

@end

此代码甚至无法构建,我在指定位置收到以下错误:

Expected '(' before 'Tile'

如果我将类型从 (Tile*) 更改为 (NSObject*),它会修复错误,这让我相信 Tile 未被识别为一种对象。

我已经通过 Google 和这个网站进行了搜索,但无法弄清楚为什么会这样。


更新

愚蠢的错误;易于修复。

正如你们都指出的那样,问题是两个头文件正在相互导入,这是不允许的。目前,我已通过将 #import "Board.h"语句移动到 Tile.m 来解决问题,因为头文件中不需要它。稍后,如果我决定在 Tile.h 文件中使用 Board,我将使用前向引用 (@class Board;),正如你们中的一些人所建议的。

再次感谢!

最佳答案

这是 headers 导入 headers 的经典问题。你在这里有一个圆圈:Tile.h 正在导入 Board.h,Board.h 导入 Tile.h。这会使编译器感到困惑——它会陷入循环。

您可以通过不将 header 导入 header 来解决此问题。但是,您仍然需要让编译器了解 Tile。在 Board.h 中,制作一个 "forward declaration"类的:

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@class Tile;    // Dear compiler, 
                // Tile is a class that I will need to refer 
                // to in this file. Please consider it to be a 
                // type; I promise it'll be defined at runtime. 
                // Sincerely, stephenalexbrowne

@interface Board : NSObject
//etc.

这向编译器保证有一个名为 Tile 的类将在运行时存在;然后您可以在标题的其余部分引用该名称。在 Board 的实现中,您导入了 Tile.h。这将使编译器在需要时看到与 Tile 类关联的方法和属性。

同样,将 #import "Board.h" 移动到 Tile.m 中。由于您没有引用 Tile.h 中的 Board 类,因此您不需要进行前向声明。

一般来说,最好只将类头导入到需要它们的实现文件中。框架 header ,因为它们永远不会导致您的代码出现循环,所以可以并且——因为您需要引用其中声明的许多类——应该导入到您的 header 中。

关于Objective-C 头文件无法将自定义对象识别为类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7896440/

相关文章:

ios - 使用 AWS DynamoDBScanExpression 查找列表中具有键的所有对象

cocoa - 如何将 NSKeyedUnarchive NSManagedObject 的子类导入到 Core Data 中?

c# - 从 C# SQLCLR 存储过程批量插入 SQL 表的最快方法

javascript - Node.js 新手;需要帮助将 npm 模块导入我的前端 vanilla JS 项目

model - Play Framework 错误: not found: type model

java - 如何解决javac编译器错误 “package com.sun.tools.internal.ws.processor.model does not exist”?

compiler-errors - 修复孤立的 libhdf5.so 和 libhdf5_hl.so 库导致 Caffe 编译错误

objective-c - 我打算如何释放从类方法返回的数组?

objective-c - 查找未使用的图像或覆盖 +imageNamed : to log images not found

objective-c - 尝试调用 [super didReceiveMemoryWarning] 时崩溃