【问题标题】:NSProgress crash on creating with KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECTS_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHEDNSProgress 在使用 KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECTS_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 创建时崩溃
【发布时间】:2017-11-29 09:22:28
【问题描述】:

我使用 NSProgress 通知复杂任务的进度(该任务由许多子任务组成,可以由其他子任务组成)。
我在 startTask 方法中创建主要进度:

- (void)_startTask
{
    _progress = [NSProgress progressWithTotalUnitCount:100]; //sometimes crash is here
    <...>
}

没有当前进度:

(lldb) po [NSProgress currentProgress]

有时我会因为奇怪的 stackTrace 崩溃:

0: 0x000000018539a7e8 in object_isClass()
1:KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 中的 0x0000000186b39fe0 ()
2: 0x0000000186b384bc 在
NSKeyValueWillChangeWithPerThreadPendingNotifications ()
3: 0x0000000186cac9c0 in -[NSProgress _setValueForKeys:settingBlock:] ()
4: 0x0000000186cacc7c in -[NSProgress setTotalUnitCount:] ()
5: 0x0000000186cab718 in +[NSProgress progressWithTotalUnitCount:] ()

这段代码在 mainThread 中执行。
为什么会发生这种情况,我可以做些什么来避免这种情况?

【问题讨论】:

  • 这有什么更新吗?请我陷入同样的​​问题

标签: ios nsprogress


【解决方案1】:

似乎您释放了一个或多个 NSProgress 对象,而没有删除它们的键值观察器。

你可以看看这个: https://github.com/AFNetworking/AFNetworking/issues/3710

来自“0xced”的评论清楚地说明了为什么会发生这种情况:

这是一些有趣的数据。

NSProgress 实例有时会被重新分配一个以前由另一个 NSProgress 实例使用的地址:例如,0x7ffa6a119730 被分配给一个下载进度,然后是一个上传进度,然后是另一个下载进度(发生崩溃的地方)。这解释了为什么在启用僵尸的情况下运行会使崩溃消失:地址永远不会被重用,因为释放的对象会变成僵尸并永远保留其原始地址。

当相同的地址 (0x7ffa6a119730) 被重用时,NSProgress 实例在创建后立即有一个观察者。那个观察者是 0x7ffa68c0bab0,一个旧的 AFURLSessionManagerTaskDelegate 实例。

【讨论】:

  • 好版本,我也有。
【解决方案2】:

自构建以来(自 iOS 10 起),我的应用在所有版本的 iOS 中都会发生此崩溃。

我的进度报告实现类似于 Apple 的 WWDC 2015 演讲中提到的内容 - Best Practices for Progress Reporting,其中进度对象通过调用 parentProgress.addChild(childProgress, withPendingUnitCount: value) 嵌套,因为父任务创建新的子任务并添加到调度队列。

我假设,当父进度对象被释放时,它将停止观察子进度变化(没有公共remove child 方法)。这应该是真的,但我怀疑实现不是线程安全的。

无论如何,我修改了我的实现以使用 1 个单个进度对象以避免多个进度对象出现问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多