在《在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。setenengine的第一行是[engine release],它使retain计数为0,对象被释放...."
然而,在阅读了第166页的这段话之后。我想知道car2的内部引擎参考与car1的引擎有什么关系。它们是两个不同的引用,当调用"[car2 setenengine: [car1 engine]]"时,car2中的引擎尚未初始化,并且与作者所说的保留的引擎没有任何关系。所以"[引擎释放]"不会将car1引擎的计数器降为0。明白我的意思了吗?这是勘误表还是我大错特错了?
((我想讨论这个特定的代码,而不是实现setter的正确方法))
setenengine:在什么类中?我猜是在车里。这个Car有一个Engine*类型的实例变量Engine。这是不相同的引擎*指针在第二个代码片段(这应该是一个控制器类与它自己的实例变量)。
首先,初始化引擎。[Engine new]
与[[Engine alloc] init]
相同(对于所有实际目的)。
你有两个Car对象和一个Engine对象。将car1中的引擎实例变量设置为指向引擎对象。然后释放原始指针。很好。然后把它也分配给car2。如果car2有一个不同的引擎,它就会被释放,并被分配新的引擎。如果它没有分配引擎,则释放消息被发送到nil(这很好),并且它也被分配。
一切都好。
PS -虽然Objective-C有new
结构,但使用它通常是一个坏主意,因为它模糊了两阶段创建模式,这是苹果框架的标准。使用alloc &init .
设置不正确。可能是:
- (void) setEngine: (Engine *) newEngine
{
if(newEngine != engine)
{
[engine release];
engine = [newEngine retain];
}
}