在“在Mac上学习Objective-C”一书中,您可以找到以下代码,我认为这是一个勘误表:
“这是编写setEngine的另一种尝试:
- (void) setEngine: (Engine *) newEngine
{
[engine release];
engine = [newEngine retain];
}
...思考这个案例:
Engine *engine = [Engine new]; // count: 1
Car *car1 = [Car new];
Car *car2 = [Car new];
[car1 setEngine: engine]; // count: 2
[engine release]; // count 1
[car2 setEngine: [car1 engine]]; //Ops...
为什么这是一个问题?这是正在发生的事情。 [car engine]返回一个指向引擎的指针,该指针的保留计数为1. setEngine的第一行是[engine release],这使得保留计数为0,一个对象被解除分配....“
然而,在阅读了第166页的这一段之后。我想知道car2中的内部引擎引用与car1中的引擎有什么关系。它们是两个不同的引用,并且在调用“[car2 setEngine:[car1 engine]]”时,car2中的引擎尚未初始化并且与作者所讨论的保留引擎无关。所以“[发动机释放]”不会减少与car1发动机的0相反。 看到我的观点?这是一个勘误还是我错了?
((我想讨论这个特定的代码,而不是实现setter的正确方法))
答案 0 :(得分:1)
setEngine是什么类:in?我假设它在汽车里。而且Car有一个类型为Engine *的实例变量叫做engine。这与第二个代码片段中的Engine *指针不同(它应该是一个带有它自己的实例变量的控制器类)。
首先,引擎IS初始化。 [Engine new]
与[[Engine alloc] init]
相同(出于所有实际目的)。
所以你有两个Car对象和一个Engine对象。您在car1中设置引擎实例变量以指向引擎对象。然后释放原始指针。精细。然后你也将它分配给car2。如果car2有不同的引擎,它会被释放并分配新的引擎。如果它没有分配引擎,则释放消息将被发送到nil(这很好),并且它也会被分配。
一切都很好。
PS - 虽然Objective-C具有new
构造,但使用它通常是一个坏主意,因为它模糊了Apple框架规范的两阶段创建模式。使用alloc&初始化。
答案 1 :(得分:-1)
设定者不对。它可能是:
- (void) setEngine: (Engine *) newEngine
{
if(newEngine != engine)
{
[engine release];
engine = [newEngine retain];
}
}