Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 另一个";保留,然后释放;问题_Objective C_Cocoa_Memory Management_Retaincount - Fatal编程技术网

Objective c 另一个";保留,然后释放;问题

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

作为一名Cocoa/Obj-C新手,我正在阅读Aaron Hillegass的《MacOS X的Cocoa编程》一书,撇开现在我们也有机会使用GC来避免所有这些推理的事实不谈,我不确定我是否理解其中一些保留的原因

特别是在Aaron给出的一个示例中,作为良好的编程实践:

- (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还很年轻。最