1

だから、「MazeCell.h」で宣言されているMazeCellというクラスがあります

#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 がメソッドを認識していないだけです。

MazeCellEdgeWall以前に宣言されていなかったためにXCodeが使用を許可しないまで、メッセージを無視することに満足していました(これらの警告とエラーはすべて異なるクラスにあります)。

だから、私は一般的なプログラミングに慣れていないので、見逃したかもしれない露骨なエラーを見た人がいるかどうか疑問に思っていました.


編集:コードが長いため、最初は含めませんでしたが、エラーが発生するコードは次のとおりです。

ここに「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

繰り返しますが、これは私がコーディングしたことを証明するために提供されています。このプログラムは機能し、前述したように、迷路セルのメソッドは実際に機能します。MazeCellEdgeExit を定義していないため、コンパイルが行われないということを除いて、Xcode が私に気にしない警告を表示しているだけです。 、しかしそれ以外の場合はコンパイルされます。


これはかなり奇妙です。しかし、MazeCell.h と MazeCell.m ファイルを複製して MzCell.h と MzCell.m に名前を変更し、MazeCell へのすべての参照を MzCell に置き換えると、このプログラムが実行されることがわかりました。

それは答えよりも多くの質問を開きますが...

4

3 に答える 3

2

すべてが私には良さそうです。クリーンでビルドしてみてください。古いオブジェクトファイルが浮かんでいて、コンパイラやリンカを混乱させている可能性があります。

古い迷路を解放しないsetMazeのように、明らかなメモリリークがいくつかありますが、コンパイルを妨げるバグを検出できませんでした。(あなたは間違いなく-initWithFrameで迷路を割り当てます:少なくともそれをリークします。)また、デフォルトのセッターセマンティクスは「retain」や「copy」ではなく「assign」です。この場合、後者の2つの動作はより理にかなっています。あなたはObjective-Cを初めて使用するので、批判ではなく建設的なフィードバックを目的としています。:-)

于 2009-08-04T06:08:54.973 に答える
1

警告を実際に生成しているコードをインクルードすることを怠っていますが、どこにいても、MazeCell.hヘッダーファイルをインポートしていないようです。

于 2009-08-03T23:09:46.060 に答える
0

割り当ておよび初期化するオブジェクト(「MazeView」)が「MazeCell」オブジェクトではない可能性があります。これは、チャックが述べたようにMazeCell.hのインポートを怠ったか、または単に独自のコードをコピーして貼り付けた結果として、間違ったクラスで「MazeView」オブジェクトを作成したことが原因である可能性があります。 MazeCellタイプのオブジェクトを作成し、「MazeView」という名前を付けるのは直感的です。

また、現在Xcodeにアクセスしてテストすることはできませんが、typedefが正しく宣言されていない可能性があります(または、その構文スタイルに慣れていないだけです)。typedefの6行をこれに置き換えてみてください。

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

編集: 実装ファイルをインクルードしたばかりなので、MazeView用であることに気付きました(7行目)が、元のヘッダーファイルはMazeCell用です。したがって、現時点では、実際にはMazeCellオブジェクト用のコードを記述していない(または投稿していない)。

また、インスタンス変数を@synthesize(またはそれらのメソッドを記述)していないのではないかと疑っています。

于 2009-08-03T23:26:49.787 に答える