gpt4 book ai didi

ios - 从可变数组中删除一系列对象时 CFRelease 崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:32:39 24 4
gpt4 key购买 nike

我们的一位测试人员报告了以下崩溃:

0 APP_NAME_WAS_HERE 0x00074892 testflight_backtrace + 158
1 APP_NAME_WAS_HERE 0x000754bc TFSignalHandler + 244
2 libsystem_c.dylib 0x378ea7ec _sigtramp + 48
3 CoreFoundation 0x30ef42e6 CFRelease + 94
4 CoreFoundation 0x30f09a36 -[__NSArrayM removeObjectAtIndex:] + 294
5 CoreFoundation 0x30f4a65e -[NSMutableArray removeObjectsInRange:] + 90
6 APP_NAME_WAS_HERE 0x000570ca -[StoryViewController rewindToChunkIndex:] + 558
7 APP_NAME_WAS_HERE 0x00057396 -[StoryViewController restartChapter] + 22

不幸的是,我们无法重现崩溃 - 我们只能通过 TestFlight 获取崩溃日志。

我们确实收到了调试日志,以确认 removeObjectsInRange 确实收到了正在执行的 NSMutableArray 的有效范围。 (此外,这会引发异常而不是发出信号,对吧?)

我唯一的想法是该对象正在获得双重释放,但我不确定在打开 ARC 的情况下这怎么可能?

请注意,被移除的对象是 UIView 子类,并且在此之前,它们中的一些或全部可能已从其父 View 中移除。所以如果他们在这个阶段被释放我不会感到惊讶,我只是不明白为什么这会导致它崩溃!

编辑:为了验证它是一个过度释放的对象,我人为地尝试过度释放一个对象(使用 CFRelease(__bridge (CFTypeRef) obj)在 ARC 环境中强制释放)以查看它将产生的崩溃日志的类型。不幸的是,它有点不同,所以也许它毕竟不是过度发布?可能是某种涂鸦?

这是一个明确的过度发布的样子:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x369c732c __pthread_kill + 8
1 libsystem_c.dylib 0x36c20208 pthread_kill + 48
2 libsystem_c.dylib 0x36c19298 abort + 88
3 libsystem_c.dylib 0x36bd437a free + 374
4 libobjc.A.dylib 0x375e4d72 object_dispose + 14
5 CoreFoundation 0x362e9618 -[NSObject dealloc] + 76
6 UIKit 0x310323a8 -[UIView dealloc] + 620
7 libobjc.A.dylib 0x375e416e _objc_rootRelease + 30
8 CoreFoundation 0x362dc2e0 CFRelease + 88
9 APP_NAME_WAS_HERE 0x000cea98 -[StoryViewController rewindToChunkIndex:] (StoryViewController.m:584)

这是过度发布的崩溃日志的样子:

最佳答案

如果查看堆栈跟踪,崩溃的发生不是因为错误的索引,而是因为对象的过度释放。

NSArray 在你添加一个对象时发送一个 retain 消息,在你删除一个对象时发送一个 release 消息。显然,该版本正在崩溃。

这意味着,您过度释放了添加到数组中的对象。

更新

您的 subview 是否被强烈拥有?您的所有权修饰符是“强”还是“弱”或 unsafe_unretained?即使在 ARC 中,如果您没有正确地“拥有”您的变量,也会有不平衡的保留调用。例如,由于您手动向另一个数组中添加和删除 View ,因此您应该“拥有”它。 Remove from superview 将向 View 发送释放,addSubview 将发送保留。当您使用 XIB 构建 View 时,XIB 加载机制使用属性的所有权修饰符,并在将其添加到 View (StoryViewController.view) 时相应地增加保留计数。由于 XIB 加载机制将其添加到 subview 中,因此您不应该卸载它。如果你想卸载它,你应该通过将你的 subview (导出)的属性类型更改为“强”来“拥有”它,否则,你最终会弄乱所有权。

在编写 ARC 所有权修饰符时,开始考虑对象图以及谁拥有什么。 ARC 不像垃圾收集。这样的事情还是会发生:)

关于ios - 从可变数组中删除一系列对象时 CFRelease 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10096759/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com