1

所以,我有一个名为 MazeCell 的类,它在“MazeCell.h”中声明

#import <Foundation/Foundation.h>

enum {
    MazeCellEdgeWall = 0,
    MazeCellEdgeGate = 1,
    MazeCellEdgeExit = 2
};
typedef NSUInteger MazeCellEdge;

@interface MazeCell : NSObject {
    MazeCellEdge left;
    MazeCellEdge right;
    MazeCellEdge down;
    MazeCellEdge up;
    NSUInteger drawCount;
    NSUInteger row;
    NSUInteger column;
}
@property MazeCellEdge left;
@property MazeCellEdge right;
@property MazeCellEdge down;
@property MazeCellEdge up;
@property NSUInteger drawCount;
@property NSUInteger row;
@property NSUInteger column;

- (id)initWithLeft:(MazeCellEdge)newLeft
             right:(MazeCellEdge)newRight
                up:(MazeCellEdge)newUp
              down:(MazeCellEdge)newDown
               row:(NSUInteger)newRow
            column:(NSUInteger)newColumn;
@end

Xcode 不断显示警告,就像"warning: 'MazeView' may not respond to '-left'"所有方法一样。有趣的是代码在模拟器上运行良好,只是 XCode 不知道方法。

我满足于忽略这些消息,直到 XCode 不允许我使用MazeCellEdgeWall它,因为它之前没有被声明(所有这些警告和错误都在不同的类中)。

因此,我想知道是否有人看到了我可能错过的任何明显错误,因为我通常是编程新手。


编辑:我最初没有包含代码,因为它很长,但这里是给出错误的代码。

这是“MazeCell.m”:

#import "MazeCell.h"

@implementation MazeCell

@synthesize left;
@synthesize right;
@synthesize down;
@synthesize up;
@synthesize drawCount;
@synthesize row;
@synthesize column;

-(id) init {
    if (self = [super init]) {
        right = MazeCellEdgeWall;
        up = MazeCellEdgeWall;
        left = MazeCellEdgeWall;
        down = MazeCellEdgeWall;
        drawCount = 0;
    }
    return self;
}

- (id)initWithLeft:(MazeCellEdge)newLeft
             right:(MazeCellEdge)newRight
                up:(MazeCellEdge)newUp
              down:(MazeCellEdge)newDown
               row:(NSUInteger)newRow
            column:(NSUInteger)newColumn
{
    if (self = [super init]) {
        left = newLeft;
        right = newRight;
        up = newUp;
        down = newDown;
        drawCount = 0;
        row = newRow;
        column = newColumn;
    }
    return self;
}
@end

这是 MazeView.h:

#import "MazeView.h"
#import "MazeCell.h"
#import "NSMutableArray+Stack.h"

#define kCellSidesSize 80.0

@implementation MazeView

@synthesize maze;
@synthesize controller;
@synthesize interfaceOrientation;

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        interfaceOrientation = UIInterfaceOrientationPortrait;
        [self setBackgroundColor:[UIColor greenColor]];
        [self setUserInteractionEnabled:YES];
        [self setMaze:[[Maze alloc] initWithSize:MazeSizeMake(4, 6)]];
    }
    return self;
}

- (void)setMaze:(Maze *)newMaze {
    maze = newMaze;
    CGRect newFrame = [self frame];
    newFrame.size = CGSizeMake([newMaze size].width * kCellSidesSize,
                               [newMaze size].height * kCellSidesSize);
    [self setFrame:newFrame];
}

- (void)setInterfaceOrientation:(UIInterfaceOrientation)newOrientation {
    if (interfaceOrientation != newOrientation) {
        interfaceOrientation = newOrientation;
        CGRect oldFrame = [self frame];
        [self setFrame:CGRectMake(oldFrame.origin.y, oldFrame.origin.x,
                                  oldFrame.size.height, oldFrame.size.width)];
        [[self superview] setContentSize:[self frame].size];
    }
}

- (void)setController:(UIViewController *)newController {
    if (controller != newController) {
        controller = newController;
    }
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    NSUInteger columns = [[self maze] size].width;
    NSUInteger rows = [[self maze] size].height;

    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextSetLineWidth(context, kCellSidesSize - 2.0);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    CGContextSetLineCap(context, kCGLineCapRound);

    BOOL isDrawing = NO;
    MazeCell *aCell;
    NSMutableArray *aStack = [[NSMutableArray alloc] init];
    NSUInteger row = 0;
    NSUInteger column = 0;

    while (YES) {
        aCell = [maze getCellInRow:row andColumn:column ofOrientation:interfaceOrientation];

        if (isDrawing) {
            CGContextAddLineToPoint(context, row * kCellSidesSize + kCellSidesSize / 2.0,
                                          column * kCellSidesSize + kCellSidesSize / 2.0);
        } else {
            isDrawing = YES;
            CGContextMoveToPoint(context,  row * kCellSidesSize + kCellSidesSize / 2.0,
                                        column * kCellSidesSize + kCellSidesSize / 2.0);
        }

        if ([aCell left] == MazeCellEdgeExit && [aCell drawCount] < 1) {
            //Warnings and errors
            [aCell setDrawCount:1];  //Warning
            column--;
        } else if ([aCell right] == MazeCellEdgeExit && [aCell drawCount] < 2) {
            //Warnings and errors
            [aCell setDrawCount:2];  //Warning
            column++;
        } else if ([aCell up] == MazeCellEdgeExit && [aCell drawCount] < 3) {
            //Warnings and errors
            [aCell setDrawCount:3];  //Warning
            row--;
        } else if ([aCell down] == MazeCellEdgeExit && [aCell drawCount] < 4) {
            //Warnings and errors
            [aCell setDrawCount:4];  //Warning
            row++;
        } else if ([aStack count] > 0) {
            aCell = [aStack pop];
            row = [aCell row];       //Warning
            column = [aCell column]; //Warning
            isDrawing = NO;
        } else {
            break;
        }
    }
    CGContextStrokePath(context);
    [aStack release];
}

@end

同样,这是为了证明我已经编写了代码。这个程序有效,正如我所说,迷宫单元方法确实有效,只是 Xcode 给了我一些我不关心的警告,除了它说我还没有定义 MazeCellEdgeExit 所以不再编译,但它确实以其他方式编译。


现在这很奇怪。但是我发现复制 MazeCell.h 和 MazeCell.m 文件并将它们重命名为 MzCell.h 和 MzCell.m,然后用 MzCell 替换对 MazeCell 的每个引用可以运行该程序。

虽然这带来的问题比它回答的要多……

4

3 回答 3

2

一切对我来说都很好。尝试清洁并构建。过时的目标文件很可能四处飘荡,使编译器或链接器感到困惑。

尽管存在许多明显的内存泄漏,例如在 setMaze: 你不释放旧迷宫的地方,但我无法检测到会阻止编译的错误。(你肯定在 -initWithFrame: 中分配了一个迷宫,所以你至少泄漏了那个。)此外,默认的 setter 语义是“assign”,而不是“retain”或“copy”——在这种情况下,似乎其中一个后两种行为会更有意义。我意识到你是 Objective-C 的新手,所以这些都是建设性的反馈,而不是批评。:-)

于 2009-08-04T06:08:54.973 回答
1

您忽略了包含实际生成警告的代码,但听起来无论它在哪里,您都没有导入 MazeCell.h 头文件。

于 2009-08-03T23:09:46.060 回答
0

您正在分配和初始化的对象(“MazeView”)可能不是“MazeCell”对象。这可能是由于忽略了 Chuck 提到的导入 MazeCell.h 或者您只是使用错误的类创建了“MazeView”对象,可能是由于复制和粘贴您自己的代码(只是猜测,因为它似乎是反的)直观地创建 MazeCell 类型的对象并将其命名为“MazeView”)。

我也怀疑,虽然现在无法访问 Xcode 进行测试,但您的 typedef 可能被错误地声明(或者我根本不熟悉那种语法风格)。尝试用这个替换你的 6 行 typedef。

typedef enum {
    MazeCellEdgeWall = 0,
    MazeCellEdgeGate = 1,
    MazeCellEdgeExit = 2
} MazeCellEdge;

编辑: 由于您刚刚包含了实现文件,我注意到它用于 MazeView(第 7 行),但您的原始头文件用于 MazeCell。所以到目前为止,您实际上还没有为 MazeCell 对象编写任何代码(或没有发布任何代码)。

我还怀疑您没有 @synthesize'ed(或为它们编写方法)您的任何实例变量。

于 2009-08-03T23:26:49.787 回答