我遇到了NSTokenFieldCell的问题,所以我继续在Xcode中创建一个新项目以隔离问题。这是我做的:
使用以下代码实现了最小可能的数据源对象:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return 1;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
return @"aa, bb";
}
起初它似乎工作正常,但是如果你双击要编辑的单元格,然后选项卡和shift + tab来来回切换单元格,最终当令牌字段单元格获得焦点时,应用程序会以BAD ACCESS崩溃
我在Lion 10.7.2中使用Xcode 4.2,其中包含Mac OS X Cocoa应用程序模板附带的所有默认设置。
答案 0 :(得分:3)
看起来像Cocoa中的一个错误。如果你打开僵尸,你会看到:
2011-10-31 00:02:43.802 tokenfieldtest[35622:307] *** -[NSTokenFieldCell respondsToSelector:]: message sent to deallocated instance 0x1da761f10
我尝试为表设置委托并实现- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
,每次都返回一个新的NSTokenFieldCell
(仅用于令牌列),但我得到了同样的错误。
答案 1 :(得分:0)
原来的解决方案带来了一个新问题。
当NSTokenFieldCell
未完全显示NSTableView
时,进入编辑状态再退出会导致table view显示异常。
所以我反复尝试以获得更好的解决方案:
class MyTokenFieldCell: NSTokenFieldCell {
override func fieldEditor(for controlView: NSView) -> NSTextView? {
return nil;
}
}
可能是NSTableView
对NSTokenFieldCell
的编辑器重用机制有问题,导致程序崩溃。
fieldEditorForView: 在这里被覆盖,返回nil,这样应该会导致每次编辑时都重新创建编辑器,避免复用,从而解决崩溃问题。
以下为原答案。
⚠️ 由于解决方案导致其他问题,请忽略。
我也遇到过这个问题。我的解决办法是暂时保留table view使用的cells。
自定义 NSTokenFieldCell:每次复制后,临时保存副本。
class MyTokenFieldCell: NSTokenFieldCell {
static var cells = [NSUserInterfaceItemIdentifier: [MyTokenFieldCell]]()
override func copy(with zone: NSZone? = nil) -> Any {
let cell = super.copy(with: zone)
guard let tokenFieldCell = cell as? MyTokenFieldCell else { return cell }
tokenFieldCell.identifier = self.identifier
guard let identifier = tokenFieldCell.identifier else { return cell }
var cells = MyTokenFieldCell.cells[identifier] ?? []
cells.append(tokenFieldCell)
if cells.count > 4 {
cells.removeFirst()
}
MyTokenFieldCell.cells[identifier] = cells
return cell
}
}
实现tableView(_:dataCellFor:row:)
的{{1}}方法,为table view提供NSTableViewDelegate
,设置标识符为:MyTokenFieldCell
<columnIdentifier>:<row>