【问题标题】:Why NSMutableDictionary setValue crashes?为什么 NSMutableDictionary setValue 崩溃?
【发布时间】:2018-05-18 11:46:39
【问题描述】:

setValue(_:forKey:) 方法有时会崩溃。我们的NSMutableDictionary 仅从主线程写入,但经常被访问。频繁访问字典会导致崩溃吗?

我猜Core Data 更改数据会更有效,但我们决定使用基于字典的持久存储。有什么方法可以更可靠地访问我们的NSMutableDictionary

无论如何,如果setValue 方法在循环中执行,我怎么知道它们会崩溃?如果我打印keyPath,将在崩溃发生之前到达循环结束,因此我无法缩小究竟是哪个setValue 调用导致崩溃。

【问题讨论】:

  • 您必须获取崩溃日志和错误消息。

标签: ios core-data nsmutabledictionary


【解决方案1】:

如果我理解正确,您的设置是这样的:仅在主线程上写入,但从其他线程读取。使用此设置:

let a = NSMutableDictionary()
let time = DispatchTime.now() + 0.01
DispatchQueue.global().asyncAfter(deadline: time) {
    for _ in 0..<10000000000000 {
        let b = self.a["\(self.a.count - 1)"]
        print(b)
    }
}

for index in 0..<1000000000000000 {
    a.setValue(NSNumber(value: index), forKey: "\(index)")
}

我确实能够重现您的问题。 这是发生崩溃时的堆栈跟踪:

Thread 1 Queue : com.apple.main-thread (serial)
#0  0x00000001115286f6 in _kernelrpc_mach_vm_deallocate_trap ()
#1  0x0000000111530a43 in mach_vm_deallocate ()
#2  0x00000001112c8477 in mvm_deallocate_pages ()
#3  0x00000001112bfdc4 in free_large ()
#4  0x000000010cc5506b in mdict_rehashd ()
#5  0x000000010cac26c6 in -[__NSDictionaryM setObject:forKey:] ()
#6  0x000000010b9382f5 in ViewController.viewDidLoad() at 

Thread 5 Queue : com.apple.root.default-qos (concurrent)
#0  0x000000010cafc454 in -[__NSDictionaryM objectForKey:] ()
#1  0x000000010d11567b in NSMutableDictionary.subscript.getter ()
#2  0x000000010d115588 in @objc NSDictionary.subscript.getter ()
#3  0x000000010b93898d in closure #1 in ViewController.viewDidLoad() at 

从主线程上的释放我猜setValue 引起了字典上的一些重新存储,并且作为同时发生的读取,它尝试读取释放的内存-> EXC_BAD_ACCESS。 总结:这应该是一个并发问题。

【讨论】:

  • 不不,读写只发生在主线程上,但相当频繁。没有使用全局线程。
  • 我明白了,那么您能否发布堆栈跟踪,也许它可以更接近解决方案。
【解决方案2】:

更有可能是其他地方的问题。尝试在异常上设置断点。这样 Xcode 就会在它发生时停止。

在断点导航器中选择Exception breakpoint...,见下图。

请注意,您也可能会在其他异常处停下来,如果它们得到处理,它们就不是错误。在这种情况下,请继续运行。

【讨论】:

  • 在为分发构建应用程序时会发生这种情况。从来没有在我的电脑上,而是在从 Test Flight 下载的测试设备上。
  • @János 为什么不获取崩溃日志并对其进行符号化?
  • Xcode 提供崩溃日志,我看到它发生在哪一行,但是可以看到局部变量的值吗?我不这么认为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多