从“学习Objective-C on the mac(第二版)”一书中。
为什么retain count
在下面的代码块中为2而不是1: -
- (void) setEngine: (Engine *) newEngine
{
[engine release];
engine = [newEngine retain];
// More BAD CODE: do not steal. Fixed version below.
} // setEngine
some_function
{
Engine *engine = [Engine new]; // count: 1
Car *car1 = [Car new];
Car *car2 = [Car new];
[car1 setEngine: engine]; // count: 2 But why? 1-1=0 (due to [engine release]
// in -(void) SetEngine.
// and after engine=[newEngine retain] retain count is 1.
[engine release]; // count 1
[car2 setEngine: [car1 engine]]; // oops!
return 0;
}
答案 0 :(得分:2)
首先,请考虑切换到ARC。普通编程中没有理由需要使用MRC。
其次,你的范围混乱了。请记住,此代码中确实有五个Engine*
指针,但只有一个Engine
对象。
some_function
内:
engine
,本地变量car1.engine
car2.engine
在setEngine:
方法中:
engine
,ivar newEngine
,参数以下是代码中发生的事情:
engine = [Engine new];
保留引擎,保留count = 1 [car1 setEngine:engine];
[engine release];
释放汽车的引擎ivar,可能设置为nil
,并且什么都不做。保留计数= 1 engine = [newEngine retain];
保留引擎,保留count = 2 [engine release];
释放引擎,保留count = 1 car2 setEngine:engine];
[engine release];
释放汽车的引擎ivar,可能设置为nil
,并且什么都不做。保留计数= 1 engine = [newEngine retain];
保留引擎,保留count = 2 现在,请帮个忙,让编译器为您处理引用计数。
答案 1 :(得分:0)
请查看我的评论
- (void) setEngine: (Engine *) newEngine
{
// setEngine: is method defined inside Car.
// so engine reference is retained by Car
// and it should be released when Car is released
// ie. in car dealloc method
[engine release];
engine = [newEngine retain];
// More BAD CODE: do not steal. Fixed version below.
} // setEngine
- (void)dealloc{
[engine release]; // Retaining count is reducing
[super dealloc];
}
some_function
{
Engine *engine = [Engine new]; // count: 1
Car *car1 = [Car new]; // +1 for car1
Car *car2 = [Car new]; // +1 for car2
[car1 setEngine: engine]; // count: 2 But why? 1-1=0 (due to [engine release]
// in -(void) SetEngine.
// and after engine=[newEngine retain] retain count is 1.
[engine release]; // count 1
[car2 setEngine: [car1 engine]]; // count 2 - Here Car2 retaining same
//engine retained by Car1. So retain
//count of engine increases.
[car1 release];// count 1
[car2 release];// count 0
return 0;
}