因此,我在主界面控制器中有一个带有 WKInterfaceTable 的 WatchKit 应用程序,故事板的出口设置为不为零,表行标识符也已设置并与字符串匹配,我正在使用 insetNumberOfRows:withRowType:
方法。
下面是接口控制器的简化代码,以便更好地理解:
class MainInterfaceController: WKInterfaceController {
@IBOutlet weak var table: WKInterfaceTable!
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
loadTableData()
}
private func loadTableData() {
table.setNumberOfRows(5, withRowType: "MyTableRow")
}
}
调用该方法时setNumberOfRows:withRowType:
,我得到一个类型的异常NSRangeException
:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 0 beyond bounds for empty array'
这与某些数组完全无关,即使我只使用一个普通整数作为行数的参数,也可能发生这种情况,就像上面的代码一样。
这是此方法的堆栈跟踪和指向最后一个成功步骤的箭头,之后应用程序抛出异常:
WatchKit`-[WKInterfaceTable setNumberOfRows:withRowType:]:
0x10e63e0ef <+0>: pushq %rbp
0x10e63e0f0 <+1>: movq %rsp, %rbp
0x10e63e0f3 <+4>: pushq %r15
0x10e63e0f5 <+6>: pushq %r14
0x10e63e0f7 <+8>: pushq %r13
0x10e63e0f9 <+10>: pushq %r12
0x10e63e0fb <+12>: pushq %rbx
0x10e63e0fc <+13>: pushq %rax
0x10e63e0fd <+14>: movq %rdx, %r12
0x10e63e100 <+17>: movq %rdi, -0x30(%rbp)
0x10e63e104 <+21>: movq %rcx, %rdi
0x10e63e107 <+24>: callq *0x1800b(%rip) ; (void *)0x000000010cc03930: objc_retain
0x10e63e10d <+30>: movq %rax, %r15
0x10e63e110 <+33>: movq 0x28461(%rip), %rdi ; (void *)0x000000010d2004e8: NSMutableArray
0x10e63e117 <+40>: movq 0x277aa(%rip), %rsi ; "array"
0x10e63e11e <+47>: callq *0x17fe4(%rip) ; (void *)0x000000010cc06000: objc_msgSend
0x10e63e124 <+53>: movq %rax, %rdi
0x10e63e127 <+56>: callq 0x10e63ee6e ; symbol stub for: objc_retainAutoreleasedReturnValue
0x10e63e12c <+61>: movq %rax, %rbx
0x10e63e12f <+64>: testq %r12, %r12
0x10e63e132 <+67>: jle 0x10e63e158 ; <+105>
0x10e63e134 <+69>: movq 0x28205(%rip), %r13 ; "setObject:atIndexedSubscript:"
0x10e63e13b <+76>: xorl %r14d, %r14d
0x10e63e13e <+79>: movq %rbx, %rdi
0x10e63e141 <+82>: movq %r13, %rsi
0x10e63e144 <+85>: movq %r15, %rdx
0x10e63e147 <+88>: movq %r14, %rcx
0x10e63e14a <+91>: callq *0x17fb8(%rip) ; (void *)0x000000010cc06000: objc_msgSend
-> 0x10e63e150 <+97>: incq %r14
0x10e63e153 <+100>: cmpq %r14, %r12
0x10e63e156 <+103>: jne 0x10e63e13e ; <+79>
0x10e63e158 <+105>: movq 0x281e9(%rip), %rsi ; "setRowTypes:"
0x10e63e15f <+112>: movq -0x30(%rbp), %rdi
0x10e63e163 <+116>: movq %rbx, %rdx
0x10e63e166 <+119>: callq *0x17f9c(%rip) ; (void *)0x000000010cc06000: objc_msgSend
0x10e63e16c <+125>: movq 0x17f9d(%rip), %r14 ; (void *)0x000000010cc039b0: objc_release
0x10e63e173 <+132>: movq %rbx, %rdi
0x10e63e176 <+135>: callq *%r14
0x10e63e179 <+138>: movq %r15, %rdi
0x10e63e17c <+141>: movq %r14, %rax
0x10e63e17f <+144>: addq $0x8, %rsp
0x10e63e183 <+148>: popq %rbx
0x10e63e184 <+149>: popq %r12
0x10e63e186 <+151>: popq %r13
0x10e63e188 <+153>: popq %r14
0x10e63e18a <+155>: popq %r15
0x10e63e18c <+157>: popq %rbp
0x10e63e18d <+158>: jmpq *%rax
有没有办法找出它发生的原因或地点?
编辑:
我尝试使用setRowTypes:
并得到了这个跟踪:
0x10ccb6fb9 <+735>: movq 0x277f0(%rip), %rsi ; "addObject:"
0x10ccb6fc0 <+742>: movq %r14, %rdx
0x10ccb6fc3 <+745>: callq *%r13
0x10ccb6fc6 <+748>: movq %r14, %rdi
0x10ccb6fc9 <+751>: movq 0x18140(%rip), %rax ; (void *)0x000000010b27c9b0: objc_release
0x10ccb6fd0 <+758>: movq %r15, %r14
0x10ccb6fd3 <+761>: movq %rax, %rbx
0x10ccb6fd6 <+764>: callq *%rbx
0x10ccb6fd8 <+766>: movq -0x70(%rbp), %rdi
0x10ccb6fdc <+770>: callq *%rbx
0x10ccb6fde <+772>: movq -0x68(%rbp), %rdi
0x10ccb6fe2 <+776>: callq *%rbx
0x10ccb6fe4 <+778>: movq -0x58(%rbp), %rdi
0x10ccb6fe8 <+782>: callq *%rbx
0x10ccb6fea <+784>: movq -0x50(%rbp), %rdi
0x10ccb6fee <+788>: callq *%rbx
0x10ccb6ff0 <+790>: movq -0x88(%rbp), %rdi
0x10ccb6ff7 <+797>: movq 0x28342(%rip), %rsi ; "setObject:atIndexedSubscript:"
0x10ccb6ffe <+804>: movq %r14, %rdx
0x10ccb7001 <+807>: movq %r12, %rcx
0x10ccb7004 <+810>: callq *%r13
-> 0x10ccb7007 <+813>: movq %r12, %r13
和之前一样,它在调用后崩溃setObject:atIndexedSubscript:
,因此与行类型字符串无关。
编辑2:
对不起,伙计们,我发现了问题所在:它是一个封闭源代码的 3rd-party 库,它将 NSArray 下标方法调配到objectAtIndex:
/ replaceObjectAtIndex:withObject:
,这是完全错误的。奇怪,我以前没有这些用例。