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?