【问题标题】:Why isn't my Cocoa selector actually being called?为什么实际上没有调用我的 Cocoa 选择器?
【发布时间】:2012-02-07 03:24:07
【问题描述】:

我被难住了。我没有任何错误甚至警告。我在调用它的行设置了一个断点,程序在那里停止,但是当我在该选择器的实际代码中设置一个断点时,程序并没有停止。我关心的选择器是toggleCellAtX:Y:。这是 SPPuzzle.m:

#import "SPPuzzle.h"

@implementation SPPuzzle

- (id)init
{
    self = [super init];
    if (self) {
        int x, y;
        for (y=0; y<3; y++)
            for (x=0; x<3; x++) {
                cells[x][y] = FALSE;
            }
    }

    return self;
}

- (BOOL)cellOnAtX:(int)x Y:(int)y {
    return cells[x][y];
}

- (void)toggleCellAtX:(int)x Y:(int)y {
    cells[x][y] = !cells[x][y];  // Breakpoint here doesn't stop program.
}

@end

这里是 SPPuzzleView.m:

#import "SPPuzzleView.h"

@implementation SPPuzzleView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        puzzleInstance = [[SPPuzzle alloc] init];
    }

    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    int x, y;

    for (y=0; y<3; y++)
        for (x=0; x<3; x++) {
            if ([puzzleInstance cellOnAtX:x Y:y]) {
                [[NSColor greenColor] set];
            } else {
                [[NSColor redColor] set];
            }

            [[NSBezierPath bezierPathWithRect:NSMakeRect(100*x, 100*y, 100, 100)] fill];
            [[NSColor blackColor] set];
            [[NSBezierPath bezierPathWithRect:NSMakeRect(100*x, 100*y, 100, 100)] stroke];
        }
}

- (void)mouseDown:(NSEvent *)theEvent {
    int x = (int)[theEvent locationInWindow].x / 100;
    int y = (int)[theEvent locationInWindow].y / 100;

    [puzzleInstance toggleCellAtX:x Y:y];  // Breakpoint here does stop program.
    [self setNeedsDisplay:TRUE];
}

@end

我添加了 cmets 来显示断点的位置。我做错了什么?

顺便说一句,我在调用方法时使用了 Step Into,但它只是转到下一行 ([self setNeedsDisplay:TRUE];)。

【问题讨论】:

  • 验证puzzleInstance 不是nil。如果您的视图是从 xib 实例化的,则可能会发生这种情况,因为 IIRC 它调用 initWithCoder: 然后 awakeFromNib 而不是 initWithFrame:。这是一个很长的镜头,但如果它有效,请告诉我,我会重新发布它作为答案。
  • @zneak 这不是一个长镜头,几乎可以肯定是问题所在。
  • 是的,没关系,我认为这就是监视列表中的 0x0 的含义。知道了。谢谢!

标签: objective-c macos cocoa debugging breakpoints


【解决方案1】:

puzzleInstance 可能是nil0x0 在监视列表中,正如您所指出的:nil 只是内存地址0 的另一个花哨名称)。如果您从 XIB 文件中实例化您的 SPPuzzleView,就会出现这种情况,因为加载机制调用 initWithCoder:(然后是 awakeFromNib)而不是 initWithFrame:,从而使您的 puzzleInstance 未初始化。

【讨论】:

  • 修复了它。谢谢!只是想知道:为什么程序不会因段错误或其他原因而崩溃?此外,这似乎是一个很容易犯的错误,应该有一个警告。
  • 那是ObjectiveC的规范。当您在nil 上调用方法时,该方法只返回nil。当你习惯了它在很多情况下会变得很方便,实际上它也很直观,就像 0 乘以某物是 0。
  • @flam2006,在nil 上调用方法将不执行任何操作并返回方法返回类型的零值。也就是说,如果该值是数字类型,则得到 0(这包括返回指针的方法);如果该值是结构或联合类型,您将得到一个零填充结构。
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多