2

我有一个应用程序,我收集了我无法重现的崩溃报告。我有一个视图控制器,它只是[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];
}

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

从我收到的反馈来看,使用相机时会出现内存警告(UIImagePickerController使用源类型UIImagePickerControllerSourceTypeCamera)。AttributesViewController由视图控制器以模态方式呈现,比呈现的层次高两层UIImagePickerController,它们不共享任何对象或其他数据。我知道相机经常会引起内存警告,所以我不确定它UIImagePickerController是否与内存消耗有关。

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

4

1 回答 1

1

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

否则,导致 didReceiveMemoryWarning 的问题将无法解决,因此将来尝试分配更多内存(即分配新对象)的尝试可能会开始失败。因此,任何依赖于这些对象的代码都会失败。您的代码实际上是否在检查分配新内容的所有时间的返回值?

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

更新:

感谢您分享您的澄清。坦率地说,我的想法不足,但还有一些想法:

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

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

  3. 该应用程序是否通常会检查以确保它的各种指针不为零?同样,我希望崩溃日志略有不同,但似乎在检查 nil 值时要格外谨慎,以确保它purgeMemoryForReason不会在你的幕后发布任何东西。

  4. 而且我想唯一的其他建议是,您的所有 didReceiveMemoryWarning 和 viewDidUnload 是否都在尽可能地释放内存警告的影响,以确保应用程序能够在这种低内存情况下幸存下来。看起来标准的didReceiveMemoryWarning会尝试卸载不活动的视图,因此您可能希望确保这些视图正确清理内存。根据有效管理您的内存,您要确保在您的viewDidUnloador中释放视图的对象didReceiveMemoryWarning

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

于 2012-05-04T03:37:58.020 回答