我已经读过,只有在保留时才会调用对象的 dealloc
该对象的计数变为零。
是的。
为简单起见,将包含currentColor 对象的类称为ColorContainer。现在,如果您创建一个 ColorContainer 的实例,如下所示:
ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1
containerColor 的保留计数变为 1。
假设您创建了一个UIColor 的实例并将该实例设置为currentColor 属性。在这种情况下,您可以采用两种不同的方式。
在第一个中,您可以创建一个如下所示的实例。如果你使用像initWithRed:green:blue:alpha: 这样的实例方法,你必须显式释放内存。
UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy
[color release]; // retain count -1, now the referenced object has a retain count of 1
在第二种方式中,您可以使用类方法(+ 符号)。在这种情况下,您不需要显式释放内存,因为在该类方法中创建的对象将在应用程序生命周期的某个时间点自动释放。
containerColor.currentColor = [UIColor whiteColor]; // retain count +1
现在假设你释放了containerColor 对象。如果 containerColor 的保留计数等于 1,则将其从使用它的对象中释放,它可以调用其 dealloc 方法,从而也解除 currentColor 引用的对象。
在这个简单的案例研究中,您必须注意,currentColor 引用的对象仅在其保留计数为 1 时才会从内存中完全删除(解除)。事实上,如果您这样做
UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2
//[color release];
你造成了内存泄漏(你明白吗?)。
总而言之,当您使用retain、copy、init 或new(与alloc-init 相同)时,您必须始终调用他们的对应方release 或autorelease。
根据经验,您需要始终平衡对象的保留计数以避免内存泄漏。
所以,作为一个比喻,你可以像一棵树一样思考记忆。假设您有一个父母 (containerColor) 和一个孩子 (currentColor)。如果父级(保留计数为 1)被释放,它会导致调用其 dealloc 方法并为其对象释放内存。如果在其 dealloc 方法中释放一个子项(保留计数为 1),则会调用其 dealloc 方法并释放内存。如果子项的保留计数大于 1,则会导致内存泄漏。
希望对你有帮助。
编辑
有关更多信息,您可以阅读About Memory Management。自 iOS 5 以来,Apple 引入了 ARC。自动引用计数是一种编译器机制,它提供了 Objective-C 对象的自动内存管理。有关信息,请参阅Transitioning to ARC Release Notes。