我从 的存在推断retain
您正在使用 MRR(手动保留和释放)。在 MRR 中,此代码导致:
@implementation ABC
-(void) fun1
{
ObjectA * obj1 = [[ObjectA alloc] init]; // retainCount = +1
ObjectA * obj2 = obj1; // unchanged
// you have one instance of `ObjectA` with a retain count of +1
// both `obj1` and `obj2` point to the same single instance
}
-(void) fun2
{
ObjectA * obj1 = [[ObjectA alloc] init]; // retainCount = +1
ObjectA * obj2 = [obj1 retain]; // retainCount = +2
// you have one instance of `ObjectA` with a retain count of +2
// both `obj1` and `obj2` point to the same single instance
}
-(void) fun3
{
ObjectA * obj1 = [[ObjectA alloc] init]; // retainCount of `obj1` object = +1
ObjectA * obj2 = [obj1 copy]; // retainCount of `obj2` object = +1
// you have two instances of `ObjectA`, each with a retain count of +1
// `obj1` points to one instance and `obj2` point to the other
}
-(void) fun4
{
ObjectA * obj1 = [[ObjectA alloc] init]; // retainCount of `obj1` object = +1
ObjectA * obj2 = [obj1 mutableCopy]; // retainCount of `obj2` object = +1
// you have two instances of `ObjectA`, each with a retain count of +1
// `obj1` points to one instance
// `obj2` points to another instance, which is mutable copy of the `obj1` instance
}
@end
显然,在所有这些情况下,在 MRR 中,如果您在方法结束时不对ObjectA
实例执行某些操作,那么您将发生泄漏(因为您放弃了对这些对象的最后一个已知引用)。如果使用 ARC,则执行必要的清理。
顺便说一句,将来您应该自己检查结果。例如,如果您将这些诊断语句添加到每个方法的末尾,您会清楚地看到发生了什么:
NSLog(@"%s: [obj1 (%p) retainCount] = %d", __FUNCTION__, obj1, [obj1 retainCount]);
NSLog(@"%s: [obj2 (%p) retainCount] = %d", __FUNCTION__, obj2, [obj2 retainCount]);
这显示了变量指向的对象的地址,以及对象的当前地址retainCount
。不用说,您不应该retainCount
在生产代码中使用它,但它仅用于诊断目的。
顺便说一句,虽然您尝试了解内存管理很好,但我建议您认真考虑使用自动引用计数(ARC)。它使内存管理更容易(不retain
,release
或retainCount
)。如果您决定坚持手动保留和释放 (MRR),请确保您通过静态分析器运行代码(Xcode 的“产品”菜单上的“分析”),因为它在识别问题方面相当不错那个瘟疫MRR代码。