Cocoa 当isGroupItem委托方法与Swift一起使用时,NSOutlineView崩溃
我想在Swift项目中使用NSOutlineView部署源代码列表 当未调用isGroupItem委托方法时,下面的视图控制器工作良好。但是,当使用isGroupItem方法时,将返回许多_unsmallocblock_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_。我不知道这些东西是从哪里来的。我提供的项目只是字符串Cocoa 当isGroupItem委托方法与Swift一起使用时,NSOutlineView崩溃,cocoa,swift,nsoutlineview,Cocoa,Swift,Nsoutlineview,我想在Swift项目中使用NSOutlineView部署源代码列表 当未调用isGroupItem委托方法时,下面的视图控制器工作良好。但是,当使用isGroupItem方法时,将返回许多_unsmallocblock_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_。我不知道这些东西是从哪里来的。我提供的项目只是字符串 class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineVi
class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {
let topLevel = ["1", "2"]
let secLevel = ["1": ["1.1", "1.2"], "2": ["2.1", "2.2"]]
func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
if let str = item as? String {
let arr = secLevel[str]! as [String]
return arr.count
} else {
return topLevel.count
}
}
func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
return outlineView.parentForItem(item) == nil
}
func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
var output: String!
if let str = item as? String {
output = secLevel[str]![index]
} else {
output = topLevel[index]
}
return NSString(string: output)
}
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
return item
}
func outlineView(outlineView: NSOutlineView, isGroupItem item: AnyObject) -> Bool {
return (outlineView.parentForItem(item) == nil)
}
func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? {
return outlineView.makeViewWithIdentifier("HeaderCell", owner: self) as NSTextField
}
}
示例项目可以下载Ken Thomases在苹果开发者论坛上回答了这个问题。以下是他所说的: 提供给大纲视图的项目必须是持久的。此外,对于给定的父项和索引,每次都必须返回相同的项。不能返回临时创建的对象,就像在-outlineView:child:ofItem:中调用NSString构造函数一样 将数据源对象持久化后,它可以正常工作,如下所示:
let topLevel = [NSString(string: "1"), NSString(string: "2")]
let secLevel = ["1": [NSString(string: "1.1"), NSString(string: "1.2")], "2": [NSString(string: "2.1"), NSString(string: "2.2")]]
然后在outlineView:child:ofItem:datasource方法中返回存储的NSString。如果您查看NSOutlineView文档,您将看到它只存储指针;它不保留从child:ofItem:delegate方法返回的对象。所以,当你做这行的时候:
return NSString(string: output)
您将返回一个新的NSString实例,该实例将被快速释放(因为outline视图不保留它)。在这一点之后,无论何时您询问有关项目的问题,您都会遇到崩溃,因为NSString已被释放
解决方案很简单:将NSString存储在一个数组中,并每次返回相同的实例
corbin这是因为
NSOutlineView
使用从NSObject
继承的对象,而Swift字符串是不兼容的类型。闻起来像个bug。如果返回true
它将崩溃。如果返回false
它将父行显示为malloc…
这可能是一个bug;它应该“起作用”,但不能。请看我的回复(马上就来)。谢谢。这有帮助。我永远也猜不到。我把这件事再弄了一点。请看这里:我认为理解这一点很重要。请看我的回答。