Nir*_*iya -3 cocoa objective-c ios
我试图了解以下四种情况的内存管理之间的区别:
@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
Run Code Online (Sandbox Code Playgroud)
我咨询过这个问题,但我仍然不清楚上述每个问题之间的区别.有人可以解释每个人做了什么,以及他们为什么不同?
我正在推断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
Run Code Online (Sandbox Code Playgroud)
显然,在所有这些情况下,在MRR中,如果ObjectA在方法结束时没有对实例执行某些操作,则会泄漏(因为您放弃了对这些对象的最后一次已知引用).如果使用ARC,则执行必要的清理.
顺便说一下,将来你应该自己检查结果.例如,如果您将这些诊断语句添加到每个方法的末尾,您将清楚地看到发生了什么:
NSLog(@"%s: [obj1 (%p) retainCount] = %d", __FUNCTION__, obj1, [obj1 retainCount]);
NSLog(@"%s: [obj2 (%p) retainCount] = %d", __FUNCTION__, obj2, [obj2 retainCount]);
Run Code Online (Sandbox Code Playgroud)
它显示变量指向的对象的地址,以及对象的当前值retainCount.毋庸置疑,您不应该retainCount在生产代码中使用它,但它仅用于诊断目的.
顺便说一下,虽然你试图理解内存管理是好的,但我建议你认真考虑使用自动引用计数(ARC).它使内存管理更容易(不retain,release或retainCount).如果您决定坚持使用手动保留和释放(MRR),那么请确保通过静态分析器(Xcode的"产品"菜单上的"分析")运行代码,因为它在识别问题时非常不错瘟疫MRR代码.