objective-c - 如何在 Objective-C 中调试单例

我的应用包含多个单例(来自 this tutorial)。但是我注意到,当应用程序因为单例而崩溃时,几乎不可能弄清楚它来自哪里。即使问题出在其中一个 Singleton 对象上,应用程序断点也会在 main 函数处给出 EXEC_BAD_ACCESS。如果我的单例对象有问题,是否有关于如何调试它们的指南?

最佳答案

如果您不想更改您的设计(如我在另一篇文章中所建议的那样),请考虑通常的调试工具:断言、单元测试、僵尸测试、内存测试(GuardMalloc、scribbling)等。这应该确定人们会遇到的绝大多数问题。

当然,对于可以做什么和不能做什么,您会有一些限制 - 特别是关于不能使用单元测试独立测试的内容。

同样,当/如果您正在处理复杂的全局状态时,在某些情况下,再现性可能会更加困难,因为您已经创建了多个强制单例。当全局状态非常大且复杂时 - 独立测试这些类型可能不会在所有情况下都有效,因为该错误可能仅出现在您的应用程序中发现的复杂全局状态中(当 4 个单例以特定方式交互时)。如果您已将问题隔离到多个单例实例(例如 MONAudioFileCache 和 MONVideoCache)的交互,将这些对象放在容器类中将允许您引入耦合,这将有助于诊断此问题。尽管增加耦合通常被认为是一件坏事;这并没有真正增加耦合(它已经作为全局状态的组件存在),而只是集中了现有的全局状态依赖性——当这些单例的状态影响其他组件时,你实际上并没有像集中它那样增加它可变的全局状态。

如果你仍然坚持使用单例,这些可能会有所帮助:

  • 要么使它们成为线程安全的,要么添加一些断言以验证突变仅发生在主线程上(例如)。太多人认为具有原子属性的对象意味着该对象是线程安全的。这是错误的。

  • 更好地封装您的数据,尤其是变异的数据。例如:让单例类将对象添加到它持有的数组中,而不是传递您的类持有的数组供客户端变异。如果您确实必须将数组公开给客户端,则返回一个副本。这只是基本的 ood,但许多 objc 开发人员公开了他们的大部分 ivar,而无视封装的重要性。

  • 如果它不是线程安全的并且该类在多线程上下文中使用,则使该类(而不是客户端)实现适当的线程安全。

  • 将单例的错误检查设计得特别健壮。如果程序员传递了无效的参数或滥用了接口(interface) - 只需断言(带有关于问题/解决方案的好消息)。

  • 编写单元测试。

  • 分离状态(例如,如果您可以轻松删除 ivar,就这样做)

  • 降低状态的复杂性。

  • 如果在使用彻底的断言、单元测试、僵尸测试、内存测试(GuardMalloc、scribbling)等编写/测试后仍然无法调试某些东西,那么您正在编写的程序过于复杂(例如将多个类之间的复杂性),或者需求与实际使用不符。如果你在那个时候,你绝对应该引用我的另一篇文章。全局变量状态越复杂,调试所需的时间就越多,当出现问题时您可以重用和测试程序的时间就越少。

祝你好运

https://stackoverflow.com/questions/7219106/

相关文章:

php - PEAR 邮件连接拒绝 smtp.gmail.com

visual-studio - Visual Studio 安装项目预生成事件

security - 如何在 Web 应用程序中保护 HTML 电子邮件?

unix - SqLite3 NFS 挂载问题与锁定 - 我可以使用类似 CIFS nobrl 的东

oop - 实现对象关联基数的模式和实践

android - 向 RadioGroup 和 Radiobutton 添加过渡动画

macos - 什么类型的文件可以在 Mac 上使用 codesign 进行签名?

php - 在 ImageMagick 中量化图像时保留 alpha channel ?

visual-studio - Visual Studio 中的自定义构建规则,具有多个输出

drupal - 如何总结 drupal 7 中 View 表的列?