Objective c 另一个";保留,然后释放;问题
作为一名Cocoa/Obj-C新手,我正在阅读Aaron Hillegass的《MacOS X的Cocoa编程》一书,撇开现在我们也有机会使用GC来避免所有这些推理的事实不谈,我不确定我是否理解其中一些保留的原因 特别是在Aaron给出的一个示例中,作为良好的编程实践:Objective c 另一个";保留,然后释放;问题,objective-c,cocoa,memory-management,retaincount,Objective C,Cocoa,Memory Management,Retaincount,作为一名Cocoa/Obj-C新手,我正在阅读Aaron Hillegass的《MacOS X的Cocoa编程》一书,撇开现在我们也有机会使用GC来避免所有这些推理的事实不谈,我不确定我是否理解其中一些保留的原因 特别是在Aaron给出的一个示例中,作为良好的编程实践: - (void) setFoo:(NSCalendarDate *)x { [x retain]; [foo release]; foo = x; } 我不明白在方法的第一行保留x实例的原因: [x r
- (void) setFoo:(NSCalendarDate *)x
{
[x retain];
[foo release];
foo = x;
}
我不明白在方法的第一行保留x实例的原因:
[x retain];
这个实例的范围就是set方法,对吗?
退出方法作用域时,无论如何都应释放x实例否?
此外,将x分配给foo时,使用:
foo = x;
foo将指向x个内存单元,因此将增加指向的对象保留计数,否?这将确保内存不会被释放
那么,重点是什么?当然,我肯定我遗漏了一些东西,但不知道具体是什么
谢谢,
Fabrizio保留意味着:我需要这个对象留在周围,它不能被释放。如果不保留x
,则可能发生以下情况:
您将x
分配给foo
,因此foo
现在指向NSCalendarDate所在的地址。有人释放或自动释放此对象,它的保留计数最终下降到0,对象被释放。现在您的foo
仍然指向该地址,但不再有有效的对象。稍后,将创建一个新对象,并且它碰巧位于与旧NSCalendarDate对象相同的地址。现在你的foo
指向一个完全不同的对象
为了防止这种情况,您需要保留它。你需要说,请不要释放对象,我需要它。一旦你用完它,你就可以释放它,这意味着我不再需要这个对象,如果没有其他人需要它,你现在就可以清理它
现在是经典的三部分作业。考虑一下你的<代码> Stfo: 看起来是这样的:
- (void) setFoo:(NSCalendarDate *)x
{
[foo release];
[x retain];
foo = x;
}
这是一个非常糟糕的主意。假设您的对象是唯一保留nScReavaDeDATE对象的对象,并且考虑您将这样做:<代码> [SoeStfFo:Fo];<代码>。听起来可能很傻,但这样的事情可能会发生。现在的流程是:
foo
将被发布。它的保留计数现在可能下降到0,对象将被释放
哎呀,我们正试图保留并访问一个解除分配的对象
这就是为什么您总是先保留
新对象,然后释放
旧对象
如果您来自Java或.NET背景,了解Foo*
类型的变量只包含对象的地址,这一点非常重要。在Java或.NET中,如果您愿意,指向对象的变量会自动“保留”对象。在Objective-C中(在非GC环境中)并非如此。你可以考虑一个变量<代码> fo*是一个弱引用,并且你需要明确告诉Objto-C你是否仍然需要那个对象在那个地址上。 保留意味着:我将需要这个对象停留在它周围,它不能被解除分配。如果不保留
x
,则可能发生以下情况:
您将x
分配给foo
,因此foo
现在指向NSCalendarDate所在的地址。有人释放或自动释放此对象,它的保留计数最终下降到0,对象被释放。现在您的foo
仍然指向该地址,但不再有有效的对象。稍后,将创建一个新对象,并且它碰巧位于与旧NSCalendarDate对象相同的地址。现在你的foo
指向一个完全不同的对象
为了防止这种情况,您需要保留它。你需要说,请不要释放对象,我需要它。一旦你用完它,你就可以释放它,这意味着我不再需要这个对象,如果没有其他人需要它,你现在就可以清理它
现在是经典的三部分作业。考虑一下你的<代码> Stfo: 看起来是这样的:
- (void) setFoo:(NSCalendarDate *)x
{
[foo release];
[x retain];
foo = x;
}
这是一个非常糟糕的主意。假设您的对象是唯一保留nScReavaDeDATE对象的对象,并且考虑您将这样做:<代码> [SoeStfFo:Fo];<代码>。听起来可能很傻,但这样的事情可能会发生。现在的流程是:
foo
将被发布。它的保留计数现在可能下降到0,对象将被释放
哎呀,我们正试图保留并访问一个解除分配的对象
这就是为什么您总是先保留
新对象,然后释放
旧对象
如果您来自Java或.NET背景,了解Foo*
类型的变量只包含对象的地址,这一点非常重要。在Java或.NET中,如果您愿意,指向对象的变量会自动“保留”对象。在Objective-C中(在非GC环境中)并非如此。可以将类型<代码> fo*的变量视为弱引用,你需要明确地告诉Objective-C你是否仍然需要那个地址的对象。谢谢你的精彩解释,DarkDust它消除了人们的疑虑,但我在我的问题中可能没有阐明的唯一一点是:行不是foo=x代码>是否要将对象x点的保留计数增加到。。。?这就是为什么我认为强制保留是无用的…哦,我刚刚又读了关于弱引用的最后一部分!这就是我的答案!我想知道为什么亚伦没有用粗体字指出这一点……这与我以前使用的其他语言有很大的不同。谢谢:)@Fabrizio Prosperi:也许亚伦没有强调这一点是因为他的背景。当他编写第一版时,.NET还不存在,Java还很年轻。最