返回

分类的误用引发的崩溃:一堂关于 Objective-C 内存管理的教训

IOS

分类误用引发的崩溃:一堂关于 Objective-C 内存管理的教训

在最近的一个开发项目中,我意外地在自定义的 UIViewController 分类中重写了 dealloc 方法,导致项目中出现了大量野指针的崩溃。虽然重写 dealloc 方法可能会引发一些不确定的行为,但我仍然不明白它为什么会导致崩溃。带着疑问,我重新回顾了 Objective-C 的内存管理知识。

Objective-C 中的内存管理

Objective-C 是一种基于引用计数的语言,这意味着对象的生命周期由引用它的变量的数量决定。当一个对象没有更多的引用指向它时,它就会被释放,它的内存会被系统回收。

在 Objective-C 中,alloc 方法分配内存并创建一个新对象,而 init 方法初始化该对象。当对象不再需要时,dealloc 方法被调用来释放其内存。

分类

分类是 Objective-C 中的一种强大的特性,它允许向现有类添加方法而不修改原始类。分类被用来扩展类的功能,而无需创建子类。

在上面的例子中,我创建了一个 UIViewController 的分类,并重写了 dealloc 方法。然而,我忘记了在分类的 dealloc 方法中调用 super,导致系统在释放对象时没有调用原始类的 dealloc 方法。

野指针

当一个对象被释放后,指向该对象的指针就会变成野指针。野指针是一个指向无效内存区域的指针,当使用野指针时,就会导致崩溃。

在我重写的分类的 dealloc 方法中,我没有调用 super,导致原始类的 dealloc 方法没有被调用。这意味着对象没有被正确释放,指向它的指针变成了野指针。当使用这些野指针时,就会导致崩溃。

修复

为了修复这个问题,我在分类的 dealloc 方法中添加了对 super 的调用:

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

通过添加对 super 的调用,我确保了原始类的 dealloc 方法被调用,对象被正确释放,野指针的问题也得到了解决。

教训

这次经历教会了我重写 dealloc 方法时的重要性。重写 dealloc 方法可能会导致意想不到的后果,例如野指针和崩溃。始终确保在分类的 dealloc 方法中调用 super,以确保原始类的 dealloc 方法被调用。

遵循 Objective-C 内存管理的最佳实践非常重要,以避免内存错误和崩溃。通过理解引用计数和 dealloc 方法的行为,我们可以写出健壮且高效的 Objective-C 代码。