2012-02-07 4 views
2

Я в тупике. У меня нет никаких ошибок или даже предупреждений. Я установил точку останова в строке, которая ее вызывает, и программа останавливается там, но когда я устанавливаю точку останова внутри фактического кода для этого селектора, программа не останавливается. Селектор, с которым я связан, - 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 

Я добавил комментарии, чтобы показать, где контрольные точки. Что я делаю не так?

Кстати, я использовал Step Into при вызове метода, но он просто переходит к следующей строке ([self setNeedsDisplay:TRUE];).

+2

Убедитесь, что 'puzzleInstance' не' nil'. Это может произойти, если ваше представление создается из xib, потому что IIRC он вызывает 'initWithCoder:' then' awakeFromNib' вместо 'initWithFrame:'. Это длинный выстрел, но если он работает, просто скажите, и я отвечу ему как ответ. – zneak

+0

@zneak Это не длинный выстрел, это почти наверняка проблема. – dasblinkenlight

+0

Да, все в порядке, я полагаю, что 0x0 в списке просмотра означает. Понял. Благодаря! – flarn2006

ответ

2

puzzleInstance вероятно nil (0x0 в списке часов, как вы отметили: nil это просто еще один причудливое имя для адреса памяти 0). Это будет иметь место, если вы создали экземпляр своего SPPuzzleView из XIB-файла, потому что механизм загрузки вызывает initWithCoder: (тогда awakeFromNib) вместо initWithFrame:, оставляя ваш puzzleInstance неинициализированным.

+0

Это исправлено. Благодаря! Просто интересно: почему бы программе не разбиться с segfault или что-то еще? Кроме того, это кажется довольно простой ошибкой, чтобы сделать предупреждение. – flarn2006

+0

Это спецификация ObjectiveC. Когда вы вызываете метод на 'nil', метод просто возвращает' nil'. Он становится удобным во многих ситуациях, когда вы привыкаете, и он на самом деле интуитивно понятен и в некотором смысле, как 0 раз что-то 0. – barley

+0

@ flam2006, вызов метода на 'nil' ничего не сделает и возвращает нулевое значение возвращаемого типа метода. То есть, если значение будет иметь числовой тип, вы получите 0 (сюда входят методы, возвращающие указатели); и если значение будет иметь структуру или тип объединения, вы получите структуру с нулевым заполнением. – zneak

Смежные вопросы