Objective c Cocoa为什么必须保留和释放函数参数?

Objective c Cocoa为什么必须保留和释放函数参数?,objective-c,cocoa,macos,Objective C,Cocoa,Macos,我正在阅读Aaron Hillegass的书,特别是彩票的例子。我有一个关于-setEntryDate:方法的问题;为什么我必须保留日期?该程序在没有保留的情况下仍然有效 -(void)setEntryDate:(NSCalendarDate *)date { [date retain]; [entryDate release]; entryDate = date; } 但这仍然很有效: -(void)setEntryDate:(NSCalendarDate *)da

我正在阅读Aaron Hillegass的书,特别是彩票的例子。我有一个关于-setEntryDate:方法的问题;为什么我必须保留日期?该程序在没有保留的情况下仍然有效

 -(void)setEntryDate:(NSCalendarDate *)date {
    [date retain];
    [entryDate release];
    entryDate = date;
}
但这仍然很有效:

-(void)setEntryDate:(NSCalendarDate *)date {
    entryDate = date;
}

那么,为什么我必须保留日期然后发布entryDate是正确的呢?

现在可以使用,但是如果您正在编写一个更大的程序,那么在将来的某个不确定的时刻,对象日期指向的对象可能会被称为setEntryDate的人发布。如果发生这种情况,它将在程序的其余部分失效。您将在类中保留此对象,因为该类现在拥有对该对象的引用,并且需要指示该引用。通过这样做,即使任何名为setEntryDate的类都要发布日期,您的类仍然会维护对它的有效引用。而且,这不仅仅是您正在编写的常规旧方法。这是一个setter,它具体负责在它所属的类上设置实例变量。如果您正在编写非setter方法,则可能不必保留参数。我想说的是,保留方法参数并不总是必要的;在这种情况下,几乎所有处理非原语类型的setter都是如此


这被称为参考计数,并被详细解释。现在,既然你才刚刚开始学习,那就不用担心阅读了。当您开始使用内存管理进入更复杂的场景时,该指南是一本非常有价值的读物。

因为您正在声明对象的所有权,而retain是如何做到这一点的。不正确的代码有时会正常工作,但这本质上只是运气


请参阅。

此类方法称为访问器方法。顾名思义,它们允许检索和设置变量——具体地说,它们被称为getter和setter

然而,您将在本书后面几章中看到的约定不仅仅是一种约定,它是为变量调用getter,例如,一个名为foo的NSString

而二传手:

- (void)setFoo:(NSString*)newFoo;
在上面的示例中,实现该方法以设置新的日期值。内存管理在第4章中进行了描述,但简而言之,Objective-C对象的工作方式是它们有一个retain计数——这表示对象拥有的引用数量;分配时,对象的保留计数为1。然后可以向对象发送retain或release消息,以分别增加或减少retain计数。retain消息意味着发送消息的对象希望使用该对象,因此保留该对象。释放消息意味着发送消息的对象不再希望使用该对象,因此减少了保留计数。当对象的保留计数达到0时,该对象将被解除分配。这样就避免了内存泄漏

保留日期而发布entryDate的原因是,日期是您想要了解的新对象;因此,您通过保留它来主张对它的所有权。entryDate变量指向当前日期对象,但由于您将其设置为新值,因此不再需要了解它;因此你释放它;这可以防止内存泄漏,因为您最初会保留此变量


正如我之前所说,一旦阅读了第4章:内存管理,这个概念就会变得更加清晰。现在,只要接受它,并在解释它时理解它背后的原因。

如果你通过视频更好地学习,斯坦福大学有一些关于iPhone开发的视频,在一定程度上也涵盖了Cocoa和Objective-C。查看第3课,它很好地概述了内存管理,并提供了示例和讨论。

顺便说一句,您的方法名为date,参数名为date,但类型似乎是NSCalendar,这不是任何想象中的日期。你的意思是使用NSDate吗?我实际上是指NSCalendarDate,谢谢你指出这一点。谢谢你的回答,Marc,这很有意义。这确实是正确的答案。不要担心其他课程在做什么。你唯一需要考虑的是“我要拥有这个物体吗?”如果是这样的话,你制作了一份副本,在这种情况下,你拥有或保留了副本。如果没有,你就没有。就这么简单。
- (void)setFoo:(NSString*)newFoo;