【问题标题】:NSTableView ViewBased crashesNSTableView ViewBased 崩溃
【发布时间】:2018-03-15 08:03:33
【问题描述】:

我提前道歉,但我无法解决这个问题。到目前为止,我已经非常广泛地使用了基于单元格的表格,并且从未遇到过这种基于视图的类型所遇到的问题。

我有一个带有托管对象列表的数组控制器。它们绑定到表格的内容,对象的名称绑定到表格的单元格视图(使用 objectValue.name)。

有一个本地数组保存数组控制器的对象。它被保留了。

我已将表的委托设置为我的视图控制器。我已经按照 Apple 文档中的说明设置了 @"MyView" 标识符。

这是我遇到问题的代码...

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

NSTableCellView *result = [tableView makeViewWithIdentifier:@"MyView" owner:self];

// Set the stringValue of the cell's text field to the nameArray value at row

result.textField.stringValue = [[localArray objectAtIndex:row] valueForKey:@"name"];

return result;

我可以看到“结果”不是 nil,并且从数组返回的值也不是 nil。然而,一旦执行了 result.textField.stringValue 行,我就会得到“EXC_BAD_INSTRUCTION”。如果我使用视图控制器作为数据源似乎没有任何区别。任何想法,将不胜感激。谢谢。

0x7fff841f13e1 <+0>:   pushq  %rbp  
    0x7fff841f13e2 <+1>:   movq   %rsp, %rbp  
    0x7fff841f13e5 <+4>:   pushq  %r14  
    0x7fff841f13e7 <+6>:   pushq  %rbx  
    0x7fff841f13e8 <+7>:   movq   %rdx, %rbx  
    0x7fff841f13eb <+10>:  movq   0x1cfe882e(%rip), %rsi    ; "description"  
    0x7fff841f13f2 <+17>:  movq   0x1cd17d5f(%rip), %r14    ; (void  *)0x00007fff9b66e000: objc_msgSend  
    0x7fff841f13f9 <+24>:  movq   %rbx, %rdi  
    0x7fff841f13fc <+27>:  callq  *%r14  
    0x7fff841f13ff <+30>:  movq   %rax, %rcx  
    0x7fff841f1402 <+33>:  leaq   0x1cd65977(%rip), %rdi    ; @"Crashing on exception: %@"  
    0x7fff841f1409 <+40>:  xorl   %eax, %eax  
    0x7fff841f140b <+42>:  movq   %rcx, %rsi  
    0x7fff841f140e <+45>:  callq  0x7fff8401d97b            ; _NSNoteInCrashReports  
    0x7fff841f1413 <+50>:  movq   0x1cfea3a6(%rip), %rsi    ; "callStackSymbols"  
    0x7fff841f141a <+57>:  movq   %rbx, %rdi  
    0x7fff841f141d <+60>:  callq  *%r14  
    0x7fff841f1420 <+63>:  movq   0x1cfeb951(%rip), %rsi    ; 
"componentsJoinedByString:"  
    0x7fff841f1427 <+70>:  leaq   0x1cd61e12(%rip), %rdx    ; @"'\n'"  
    0x7fff841f142e <+77>:  movq   %rax, %rdi  
    0x7fff841f1431 <+80>:  callq  *0x1cd17d21(%rip)         ; (void *)0x00007fff9b66e000: objc_msgSend  
    0x7fff841f1437 <+86>:  movq   0x1cfeaa9a(%rip), %rsi    ; "UTF8String"  
    0x7fff841f143e <+93>:  movq   %rax, %rdi  
    0x7fff841f1441 <+96>:  callq  *0x1cd17d11(%rip)         ; (void *)0x00007fff9b66e000: objc_msgSend  
    0x7fff841f1447 <+102>: movq   %rax, 0x1d05a372(%rip)    ; gCRAnnotations + 24  
->  0x7fff841f144e <+109>: ud2      
    0x7fff841f1450 <+111>: movq   %rax, %rdi  
    0x7fff841f1453 <+114>: callq  0x7fff849f0c86            ; symbol stub for: objc_begin_catch  
    0x7fff841f1458 <+119>: xorl   %edi, %edi  
    0x7fff841f145a <+121>: xorl   %esi, %esi  
    0x7fff841f145c <+123>: xorl   %eax, %eax  
    0x7fff841f145e <+125>: callq  0x7fff8401d97b            ; _NSNoteInCrashReports  
    0x7fff841f1463 <+130>: callq  0x7fff849f0caa            ; symbol stub for: objc_exception_rethrow  
    0x7fff841f1468 <+135>: movq   %rax, %rbx  
    0x7fff841f146b <+138>: callq  0x7fff849f0c9e            ; symbol stub for: objc_end_catch  
    0x7fff841f1470 <+143>: movq   %rbx, %rdi  
    0x7fff841f1473 <+146>: callq  0x7fff849f06d4            ; symbol stub for: _Unwind_Resume  
    0x7fff841f1478 <+151>: callq  0x7fff849f0d58            ; symbol stub for: objc_terminate  
    0x7fff841f147d <+156>: nop      
    0x7fff841f147e <+157>: nop      
    0x7fff841f147f <+158>: nop  

【问题讨论】:

  • 你只有一个表列?
  • 显示崩溃的堆栈跟踪。事实上,最好显示完整的崩溃报告。
  • 永远不要使用 valueForKey 从字典中获取单个值,除非您可以解释为什么明确需要 KVC。专用语法为objectForKey 或密钥订阅:localArray[row][@"name"]
  • @vadian valueForKey: 适用于托管对象。
  • @Willeke 这确实是使用 KVC 的一种解释 ;) 但是 NSManagedObject 子类会更方便。

标签: objective-c macos nstableview


【解决方案1】:

我查看了 Apple 的 TableViewPlayground 代码,发现这行类似于...

NSTableCellView *result = [tableView makeViewWithIdentifier:@"MyView" owner:self];

不同之处在于他们发送的所有者对象是 nil...

NSTableCellView *result = [tableView makeViewWithIdentifier:@"MyView" owner:nil];

在我的代码中进行调整会产生重大影响。然而,这样做的重点是允许用户直接编辑单元格中的数据。由于所有者现在为零(NSObject),我的控制器不再是目标,并且编辑 textField 后的操作没有被调用。我记得在 Apple 的文档中阅读过……

注意:调用 makeViewWithIdentifier:owner: 会导致 awakeFromNib 在您的应用中被多次调用。这是因为 makeViewWithIdentifier:owner: 使用传入的所有者加载了一个 NIB,并且所有者也收到了一个 awakeFromNib 调用,即使它已经唤醒了。

我在 awakeFromNib 方法中修改了我的代码,因此它只被调用了一次,然后犹豫地将 makeViewWithIdentifier: 改回“所有者”而不是“nil”。那行得通!这就是我崩溃的最初原因。

感谢所有回复并帮助我解决问题的人。我很感激。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多