我使用 NSProgress 来通知复杂任务的进度(该任务由许多子任务组成,可以由其他子任务组成)。
我在 startTask 方法中创建主要进度:
- (void)_startTask
{
_progress = [NSProgress progressWithTotalUnitCount:100]; //sometimes crash is here
<...>
}
Run Code Online (Sandbox Code Playgroud)
没有当前进度:
(lldb) po [NSProgress currentProgress]
nil
有时我会因为奇怪的 stackTrace 崩溃:
0:0x000000018539a7e8在object_isClass()
1:0x0000000186b39fe0在KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED()
2:0x0000000186b384bc在
NSKeyValueWillChangeWithPerThreadPendingNotifications()
3:0x0000000186cac9c0在- [NSProgress _setValueForKeys:settingBlock:]()
4:0x0000000186cacc7c在- [NSProgress setTotalUnitCount:]()
5:0x0000000186cab718在 +[NSProgress progressWithTotalUnitCount:] ()
此代码在 mainThread 中执行。
为什么会发生这种情况,我可以做些什么来避免这种情况?
小智 5
似乎您释放了一个或多个 NSProgress 对象而没有删除它们的键值观察者。
你可以看看这个:https : //github.com/AFNetworking/AFNetworking/issues/3710
来自“0xced”的评论清楚地说明了为什么会发生这种情况:
这是一些有趣的数据。
NSProgress 实例有时会被重新分配一个先前由另一个 NSProgress 实例使用的地址:例如,0x7ffa6a119730 被分配给一个下载进度,然后是一个上传进度,然后是另一个下载进度(发生崩溃的地方)。这解释了为什么在启用僵尸的情况下运行会使崩溃消失:地址永远不会被重用,因为释放的对象会变成僵尸并永远保留其原始地址。
当相同的地址 (0x7ffa6a119730) 被重用时,NSProgress 实例在创建后立即有一个观察者。该观察者是 0x7ffa68c0bab0,一个旧的 AFURLSessionManagerTaskDelegate 实例。
| 归档时间: |
|
| 查看次数: |
1603 次 |
| 最近记录: |