objective-c - 尝试调用 [super didReceiveMemoryWarning] 时崩溃

标签 objective-c ios memory-management segmentation-fault

我有一个应用程序,我已经为它收集了无法重现的崩溃报告。我有一个 View Controller ,它在处理自己的内存警告时只是调用 [super didReceiveMemoryWarning] (是的,我知道我不需要这样做,但这并不能解决我的问题我现在也有)。一旦父 UIViewController 尝试调用 purgeMemoryForReason,它就会崩溃

相关跟踪信息如下:

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0x90000008
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                     0x361dbf78 objc_msgSend + 16
1   UIKit                               0x31fbf499 -[UIViewController purgeMemoryForReason:] + 65
2   MyApp                               0x00016f0d -[AttributesViewController didReceiveMemoryWarning] (AttributesViewController.m:76)
3   Foundation                          0x30c5b4ff __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 19
4   CoreFoundation                      0x34d86547 ___CFXNotificationPost_block_invoke_0 + 71
5   CoreFoundation                      0x34d12097 _CFXNotificationPost + 1407
6   Foundation                          0x30bcf3eb -[NSNotificationCenter postNotificationName:object:userInfo:] + 67
7   Foundation                          0x30bd0c1b -[NSNotificationCenter postNotificationName:object:] + 31
8   UIKit                               0x31f8a271 -[UIApplication _performMemoryWarning] + 81
9   UIKit                               0x31f8a36b -[UIApplication _receivedMemoryNotification] + 175
10  libdispatch.dylib                   0x30de42e1 _dispatch_source_invoke + 517
11  libdispatch.dylib                   0x30de1b81 _dispatch_queue_invoke$VARIANT$mp + 53
12  libdispatch.dylib                   0x30de1ec1 _dispatch_main_queue_callback_4CF$VARIANT$mp + 157
13  CoreFoundation                      0x34d8d2ad __CFRunLoopRun + 1269
14  CoreFoundation                      0x34d104a5 CFRunLoopRunSpecific + 301
15  CoreFoundation                      0x34d1036d CFRunLoopRunInMode + 105
16  GraphicsServices                    0x3600c439 GSEventRunModal + 137
17  UIKit                               0x31e06e7d UIApplicationMain + 1081
18  MyApp                               0x0000243b main (main.m:15)

我希望我能重现错误,但无论我在我的测试设备或模拟器上触发多少次内存警告,我都无法让它发生。任何有关我可能寻找的内容的帮助将不胜感激,因为我已经尝试查找但没有找到任何指向我潜在问题的信息。谢谢!

编辑:正如我所说,我没有在 didReceiveMemoryWarning 中做任何事情:

- (void) didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

是的,我知道我不需要这样做。我计划删除这段代码(我什至不知道为什么我仍然把它放在那里),但我想确保我已经解决了问题的根源。我也没有在 AttributesViewController 中实现 viewDidUnload。我还应该提到我正在使用 ARC,但我不确定这在这里是否重要。

根据我收到的反馈,使用相机时会出现内存警告(UIImagePickerController,源类型为 UIImagePickerControllerSourceTypeCamera)。 AttributesViewController 由比呈现 UIImagePickerController 的 View Controller 高两层的 View Controller 以模态方式呈现,它们不共享任何对象或其他数据。我知道相机经常会导致内存警告,所以我不确定 UIImagePickerController 除了占用内存之外是否有任何关联。

我将 Xcode 设置为始终运行分析器,这没有出现任何问题。我还通过 Zombies 和 Leaks 工具运行代码,但无法重现问题或发现任何其他问题。

最佳答案

你在 didReceiveMemoryWarning 中做什么?你在释放任何内存吗?关闭 View ?什么?邮政编码! [我看到您发布了更多代码。谢谢。]

否则,导致 didReceiveMemoryWarning 的问题将不会得到解决,因此以后尝试分配更多内存(即分配新对象)的尝试可能会开始失败。因此,任何依赖于这些对象的代码都将失败。您的代码是否真的在每次分配新内容时检查返回值?

更重要的是,您是否已确定收到这些内存警告的原因?当然,优雅地处理低内存情况是至关重要的,但如果人力可能的话,防止它们同样重要(如果不是更重要的话)。您是否通过分析器(命令+shift+B)运行您的代码?您是否分析了您的应用程序(命令+I)以识别任何泄漏源?

更新:

感谢分享您的说明。坦率地说,我的想法不多了,但还有一些想法:

  1. 当您无法重现问题时,很难诊断(更不用说修复)。这似乎真的是当务之急。如果你在 iPhone 4 或 4S 上测试,你会享受 512MB DRAM,但 3G 只有 256MB,而 3 有 128MB。您是否在较新的设备上进行测试,而用户可能有 less capable devices ?还是您的崩溃日志来自配备相当的设备?根据设备配置的不同,您可能会在不同的时间收到 didReceiveMemoryWarning,因此可能更难显示用户看到的崩溃。

  2. 为什么应用会崩溃?它可能源于 didReceiveMemoryWarning 无法释放足够的内存以继续操作(即所需对象的后续 alloc 失败),但我不确定是否表明了这一点通过你的崩溃日志。日志让我想知道你是否在做任何Key Value Observing或任何 NSNotificationCenter逻辑?我问是因为你可以想象在没有移除观察者的情况下释放观察到的对象所引起的问题。我之所以这样问,是因为我看到了 addObserver:selector:name:object: 引用,但不知道这是不是 Cocoa 在后台执行的操作,或者您的应用程序是否在自行执行。 (而且它可能不相关。)是否所有崩溃日志都显示了类似的调用堆栈?

  3. 应用通常会检查以确保它的各种指针不为零吗?同样,我希望崩溃日志略有不同,但在检查 nil 值时格外谨慎以确保 purgeMemoryForReason 没有在幕后释放某些东西似乎是谨慎的你。

  4. 我想唯一的其他建议是,您的所有 didReceiveMemoryWarning 和 viewDidUnload 是否都释放了它们所能释放的一切,以最大限度地减少内存警告的影响,确保应用程序在这种低内存情况下存活下来。看起来像标准的 didReceiveMemoryWarning将尝试卸载不活动的 View ,因此您可能希望确保这些 View 正确清理内存。根据 Managing Your Memory Efficiently ,您要确保在 viewDidUnloaddidReceiveMemoryWarning 中释放 View 的对象。

抱歉,我没有更具建设性的建议。希望其他人能够提出一些更好的想法。

关于objective-c - 尝试调用 [super didReceiveMemoryWarning] 时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10441929/

相关文章:

c - numa 分配的内存由两个 fork 进程共享?

iOS 以编程方式触发的 segue 在成功时执行多次

objective-c - 一次性从多个 NSArray 记录填充 NSTableView

ios - 根据调整大小的 UIImage 变换线点

objective-c - AC3音频无法在波斯语下的Mountain Lion上运行

java - JBoss不释放内存

ios - iOS 中的 Replace Segue 是什么?

ios - 如何使用后台点击隐藏数字键盘?

ios - 将 UILabel 的基类 UIView 更改为自定义 UIView?

c++ - 用于分配/释放 I/O 缓冲区的现代 C++ 习惯用法