我试图理解以下四种情况的内存管理之间的区别:
@implementation ABC
-(void) fun1
{
ObjectA * obj1 = [[ObjectA alloc] init];
ObjectA * obj2 = obj1;
}
-(void) fun2
{
ObjectA * obj1 = [[ObjectA alloc] init];
ObjectA * obj2 = [obj1 retain];
}
-(void) fun3
{
ObjectA * obj1 = [[ObjectA alloc] init];
ObjectA * obj2 = [obj1 copy];
}
-(void) fun4
{
ObjectA * obj1 = [[ObjectA alloc] init];
ObjectA * obj2 = [obj1 mutableCopy];
}
@end
我咨询了this question,但我仍然不清楚上述各方面之间的差异。有人可以解释每个人做了什么,以及他们为什么不同?
答案 0 :(得分:6)
我从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
,但它仅用于诊断目的。
顺便说一下,虽然你试图理解内存管理是好的,但我建议你认真考虑使用automatic reference counting(ARC)。它使内存管理变得更加容易(没有retain
,release
或retainCount
)。如果您决定坚持使用手动保留和释放(MRR),那么请确保通过静态分析器运行代码(Xcode的“产品”菜单上的“分析”),因为它在识别问题时非常不错那可能是MRR代码。
答案 1 :(得分:1)
每当你写保留它只是一个简单的区别它将增加计数,每当你写副本时它将作出参考并且不增加计数例如让我们说: -
NSObject *ret=[obj1 retain];
It will increment the count by 1in
memory(count will become 2)
NSObject *cop=[obj1 copy];
It will not increment the count here count will
be 1only it just create the new reference in
memory. (count will remain same 1 only)