滚动 UITableView 时随机崩溃
Random crash while scrolling UITableView
我有一个应用程序有一个 table 视图,可以有数百个单元格,我在做一个简单的滚动时随机崩溃,同时与 Xcode.[=12= 断开连接]
table 使用存储在 Realm 中的对象数组。大多数单元格都是从该数组填充的,除了第 0 行,它有一个摘要并直接读取领域对象。
我正在尝试重现崩溃(使用大量忍者滚动)但没有成功
这是代码片段:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
let count = "\(ItemsManager.shared.allActiveItems.count)" // ** Read from Realm **
cell.labellTotal.text = count
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
cell.labelTag.text = itemsArray[indexPath.row - 1]
return cell
}
}
我将 crashLog 导入到 Xcode/Devices 并对其进行了部分符号化,但我不清楚发生了什么。 (构建是在同一个 Mac 中完成的)
回溯显示了对 CellForRow(atIndexPath:) 的访问,然后是 Realm 的几个实例。我附加的日志的最后一部分显示线程 0 崩溃,但它不是很有帮助(线程 0 崩溃:)
知道哪里出了问题吗?
这是崩溃日志的摘要:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Filtered syslog:
None found
Last Exception Backtrace:
0 CoreFoundation 0x184966d8c __exceptionPreprocess + 228
1 libobjc.A.dylib 0x183b205ec objc_exception_throw + 55
2 Realm 0x103af598c 0x1039d4000 + 1186188
3 Realm 0x103af77c8 0x1039d4000 + 1193928
4 Realm 0x103af7798 0x1039d4000 + 1193880
5 App Name Dev 0x1027cd180 ItemsViewController.tableView(_:cellForRowAt:) + 1495424 (ItemsViewController.swift:274)
6 App Name Dev 0x1027ce3ec @objc ItemsViewController.tableView(_:cellForRowAt:) + 1500140 (ItemsViewController.swift:0)
7 UIKit 0x18e6400cc -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 667
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001843ed2ec __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001845926a8 pthread_kill$VARIANT$armv81 + 360
2 libsystem_c.dylib 0x000000018435bd0c abort + 140
3 libc++abi.dylib 0x0000000183af72c8 __cxa_bad_cast + 0
4 libc++abi.dylib 0x0000000183af7470 default_unexpected_handler+ 5232 () + 0
5 libobjc.A.dylib 0x0000000183b208d4 _objc_terminate+ 35028 () + 124
6 libc++abi.dylib 0x0000000183b1137c std::__terminate(void (*)+ 111484 ()) + 16
7 libc++abi.dylib 0x0000000183b10f78 __cxa_rethrow + 144
8 libobjc.A.dylib 0x0000000183b207ac objc_exception_rethrow + 44
9 CoreFoundation 0x000000018482ce18 CFRunLoopRunSpecific + 664
10 GraphicsServices 0x0000000186811020 GSEventRunModal + 100
11 UIKit 0x000000018e849758 UIApplicationMain + 236
12 App Name Dev 0x0000000102702b6c main + 666476 (AppDelegate.swift:20)
13 libdyld.dylib 0x00000001842bdfc0 start + 4
这个问题可能是因为以下几点:
- 您在错误的线程中使用 Realm
- 您同步使用 Realm,它会阻塞主线程
- 您使用 Realm async,如果单元正在重用且操作仍在进行中,请不要取消操作
一种可能是您使用强制施法 (as!
)。更改此行:
let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
收件人:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as? SummaryCell else {
fatalError("Unable to dequeue cell with identifier 'SummaryCell'. Exiting.")
}
对 tableView.dequeueReusableCell()
的另一个调用进行相同的更改。然后重新运行你的代码,看看会发生什么。
如果强制转换是问题,您仍然会崩溃,但您会在控制台中看到一个非常清楚的错误,告诉您崩溃的原因。
我有一个应用程序有一个 table 视图,可以有数百个单元格,我在做一个简单的滚动时随机崩溃,同时与 Xcode.[=12= 断开连接]
table 使用存储在 Realm 中的对象数组。大多数单元格都是从该数组填充的,除了第 0 行,它有一个摘要并直接读取领域对象。
我正在尝试重现崩溃(使用大量忍者滚动)但没有成功
这是代码片段:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
let count = "\(ItemsManager.shared.allActiveItems.count)" // ** Read from Realm **
cell.labellTotal.text = count
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
cell.labelTag.text = itemsArray[indexPath.row - 1]
return cell
}
}
我将 crashLog 导入到 Xcode/Devices 并对其进行了部分符号化,但我不清楚发生了什么。 (构建是在同一个 Mac 中完成的)
回溯显示了对 CellForRow(atIndexPath:) 的访问,然后是 Realm 的几个实例。我附加的日志的最后一部分显示线程 0 崩溃,但它不是很有帮助(线程 0 崩溃:)
知道哪里出了问题吗?
这是崩溃日志的摘要:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Filtered syslog:
None found
Last Exception Backtrace:
0 CoreFoundation 0x184966d8c __exceptionPreprocess + 228
1 libobjc.A.dylib 0x183b205ec objc_exception_throw + 55
2 Realm 0x103af598c 0x1039d4000 + 1186188
3 Realm 0x103af77c8 0x1039d4000 + 1193928
4 Realm 0x103af7798 0x1039d4000 + 1193880
5 App Name Dev 0x1027cd180 ItemsViewController.tableView(_:cellForRowAt:) + 1495424 (ItemsViewController.swift:274)
6 App Name Dev 0x1027ce3ec @objc ItemsViewController.tableView(_:cellForRowAt:) + 1500140 (ItemsViewController.swift:0)
7 UIKit 0x18e6400cc -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 667
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001843ed2ec __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001845926a8 pthread_kill$VARIANT$armv81 + 360
2 libsystem_c.dylib 0x000000018435bd0c abort + 140
3 libc++abi.dylib 0x0000000183af72c8 __cxa_bad_cast + 0
4 libc++abi.dylib 0x0000000183af7470 default_unexpected_handler+ 5232 () + 0
5 libobjc.A.dylib 0x0000000183b208d4 _objc_terminate+ 35028 () + 124
6 libc++abi.dylib 0x0000000183b1137c std::__terminate(void (*)+ 111484 ()) + 16
7 libc++abi.dylib 0x0000000183b10f78 __cxa_rethrow + 144
8 libobjc.A.dylib 0x0000000183b207ac objc_exception_rethrow + 44
9 CoreFoundation 0x000000018482ce18 CFRunLoopRunSpecific + 664
10 GraphicsServices 0x0000000186811020 GSEventRunModal + 100
11 UIKit 0x000000018e849758 UIApplicationMain + 236
12 App Name Dev 0x0000000102702b6c main + 666476 (AppDelegate.swift:20)
13 libdyld.dylib 0x00000001842bdfc0 start + 4
这个问题可能是因为以下几点:
- 您在错误的线程中使用 Realm
- 您同步使用 Realm,它会阻塞主线程
- 您使用 Realm async,如果单元正在重用且操作仍在进行中,请不要取消操作
一种可能是您使用强制施法 (as!
)。更改此行:
let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
收件人:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as? SummaryCell else {
fatalError("Unable to dequeue cell with identifier 'SummaryCell'. Exiting.")
}
对 tableView.dequeueReusableCell()
的另一个调用进行相同的更改。然后重新运行你的代码,看看会发生什么。
如果强制转换是问题,您仍然会崩溃,但您会在控制台中看到一个非常清楚的错误,告诉您崩溃的原因。