问题描述
在在 Mac 上学习 Objective-C"一书中,您可以找到以下我认为是勘误表的代码:
In the book "Learn Objective-C on the Mac' you can find the following code which I think is an errata:
这是编写 setEngine 的另一个尝试:
"Here's another attempt at writing 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...
为什么会出现这个问题?这就是正在发生的事情.[汽车引擎] 返回一个指向引擎的指针,其保留计数为 1.setEngine 的第一行是 [engine release],这使得保留计数为 0,对象被释放......"
Why is this a problem? Here's what's happening. [car engine] returns a pointer to engine which has a retain count of 1. The first line of setEngine is [engine release], which makes the retain count 0, an the object gets deallocated...."
但是,在阅读了第 166 页的这段之后.我想知道 car2 中的内部引擎引用与 car1 中的引擎有什么关系.它们是两个不同的引用,并且在调用[car2 setEngine: [car1 engine]]"时,car2 中的引擎尚未初始化,并且与作者所说的保留引擎没有任何关系.因此,[引擎发布]"不会将 car1 引擎的 te 计数器减少到 0.明白我的意思了吗?是勘误表还是我错了?
However, after reading this paragraph on page 166. I wonder what the internal engine reference in car2 has to do with engine in car1. They are two different references and by te time "[car2 setEngine: [car1 engine]]" is invoke, the engine in car2 hasn't been initialized and keeps no relation to the retained engine the author talks about. So "[engine release]" won't decrease te counter to 0 of car1 engine.See my point? Is it an errata or am I terrible wrong?
((我想讨论这个特定的代码,而不是实现 setter 的正确方法))
((I would like to discuss this particular code, not the right way of implementing a setter))
推荐答案
setEngine: in 是什么类?我假设它在汽车中.并且那个 Car 有一个 Engine* 类型的实例变量,称为引擎.这与第二个代码片段中的 Engine* 指针不同(它应该是一个具有自己实例变量的控制器类).
What class is setEngine: in? I'm assuming it's in Car. And that Car has an instance variable of type Engine* called engine. Which is NOT the same Engine* pointer as in the second code fragment (which should be a controller class with it's own instance variables).
首先,引擎被初始化.[Engine new]
与 [[Engine alloc] init]
相同(出于所有实际目的).
First, engine IS initialized. [Engine new]
is the same (for all practical purposes) as [[Engine alloc] init]
.
所以你有两个 Car 对象和 1 个 Engine 对象.您将 car1 中的引擎实例变量设置为指向引擎对象.然后释放原来的指针.美好的.然后你也将它分配给 car2.如果 car2 有不同的引擎,它会被释放并分配新的引擎.如果它没有分配引擎,则发布消息将被发送到 nil(这很好),并且它也会被分配.
So you've got two Car objects, and 1 Engine object. You set the engine instance variable in car1 to point to the engine object. Then release the original pointer. Fine. Then you assign it to car2 as well. If car2 had a different engine, it gets released and the new one assigned. If it didn't have an engine assigned, the release message gets sent to nil (which is fine), and it gets assigned as well.
一切都好.
PS - 虽然 Objective-C 具有 new
构造,但使用它通常是一个坏主意,因为它掩盖了 Apple 框架规范的两阶段创建模式.使用 alloc &初始化.
PS - while Objective-C has the new
construct, it's generally a bad idea to use it because it obscures the two-stage creation pattern that is the norm for Apple frameworks. Use alloc & init.
这篇关于“在 Mac 上学习 Objective-C"勘误表书本还是记忆力不好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!