尝试访问[NSView nextResponder]时Mac OS X应用程序崩溃

时间:2014-01-27 09:42:23

标签: objective-c macos crash nsview

NSTableView使用MyTableRowView(自定义NSView子类)作为内容:

- (NSView *)tableView:(NSTableView *)tb viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    ...
    MyTableRowView *rowView = [[MyTableRowView alloc] init];
    rowView.delegate = self.RowHandler;
    ...
    return rowView;
}

MyTableRowView的实现:

// MyTableRowView.h
...
@property (nonatomic, unsafe_unretained) NSObject <MyTableRowViewDelegate> *delegate;


// MyTableRowView.m
...
- (void)mouseEntered:(NSEvent *)theEvent {
    if ([self.delegate respondsToSelector:@selector(mouseEnteredRow:)])
        [self.delegate mouseEnteredRow:self];

    [[self nextResponder] mouseEntered:theEvent];
}

问题1: TableView在Windows中使用,与[NSApp beginSheet:...]一起显示。当工作表被解除时,它会被动画显示在视图之外。当此动画期间鼠标光标位于MyTableRowView上时[MyTableRowView mouseEntered:]仍会被调用。

似乎NSTableView(以及用作MyTableRowViews的委托的“RowHandler”)此时已经被释放。因此,当MyTableRowView尝试访问其委托时,应用程序与EXC_BAD_ACCESSS崩溃。

我不明白为什么MyTableRowView在释放表时仍可以正常运行但是就是这样。

我通过将委托定义为而不是 unsafe_unretained 来解决了这个问题。这样,引用设置为NIL,尽管对象已被释放,但仍可以使用它。

这是正确的方法吗?

问题2: 访问委托但访问nextResponder时,应用程序不会再崩溃。正确的点击/拖放处理需要调用nextResponder。

据我所知,没有办法判断一个对象是否已被解除分配。那么如何检查我是否可以使用nextResponder?

0 个答案:

没有答案