Objective c 释放和保留

Objective c 释放和保留,objective-c,release,retain,Objective C,Release,Retain,假设我执行以下操作(foo以某个对象开始): 只要我不重新分配foo,在这结束时,我仍然会有相同的foo,对吗?我不会在比赛中失去福的,是吗 我想我正在确保我对发布的理解是正确的。如果我释放foo,它实际上不会消失,直到它的所有句柄都消失。换句话说,必须将foo分配给//STUFF中的某个其他对象,或者foo必须超出//STUFF中的范围(并且可能创建了一个新的foo),才能删除实际的原始foo对象,对吗 编辑动机: 我想这样做的原因是假设我有以下switch语句: switch (test)

假设我执行以下操作(foo以某个对象开始):

只要我不重新分配foo,在这结束时,我仍然会有相同的foo,对吗?我不会在比赛中失去福的,是吗

我想我正在确保我对发布的理解是正确的。如果我释放foo,它实际上不会消失,直到它的所有句柄都消失。换句话说,必须将foo分配给//STUFF中的某个其他对象,或者foo必须超出//STUFF中的范围(并且可能创建了一个新的foo),才能删除实际的原始foo对象,对吗

编辑动机:

我想这样做的原因是假设我有以下switch语句:

switch (test)
{
   case 1:
      foo = [A alloc];
      [foo inita];
      break;
   case 2:
      foo =  [B alloc];
      [foo initb];
      break;
   case 3: 
      [foo setupc];
      break;
   case 4:
      f = [D alloc];
      [foo initd];
      break;
}
在切换之前释放foo并在切换结束时保留它是有意义的。案件3除外。所以,我在想,如果按照我的建议去做是安全的,那么代码可能会更简单

当然,我可以在每个alloc/init周围放置一个release/retain对,但这是大量复制的代码


一个[foo autorelease],然后retain可能会起作用。

如果
foo
的retain计数在该代码开头变为零,它将被删除并停止工作。如果您想执行类似操作,请使用
autorelease
<根据文档,code>release在垃圾收集环境中是不可操作的-也许这就是你所想的?

如果
foo
的保留计数在代码开始时变为零,它将被删除并停止工作。如果您想执行类似操作,请使用
autorelease
<根据文档,code>release在垃圾收集环境中是不可操作的-也许这就是你所想的?

所有
release
所做的就是减少每个对象都具有的引用计数器


我不知道你为什么要像你所展示的那样
释放
保留

所有
释放
所做的就是减少每个对象都具有的引用计数器


我不知道你为什么要像你所展示的那样
发布
保留

不,下面是发生的情况:

-release
方法递减保留计数,然后检查它现在是否为零。如果保留计数为零,
-release
调用
[self-dealloc]
,这会导致立即释放对象。因此,根据您的示例,在发送
-retain
消息之前发送
-release
,可能会导致应用程序崩溃

根据您添加的注释,这里有一种编写代码的替代方法,我认为它可以实现您想要的功能,同时避免代码重复:

Class class = Nil;

// Decide which class (if any) to use...
switch (test)
{
    case 1: class = [A class];  break;
    case 2: class = [B class];  break;
    case 3: class = foo == nil ? Nil : [C class]; break;
    case 4: class = [D class];  break;
}

// If a class was selected, create a new instance 
// and release the previous one...
if (class != Nil)
{
    [foo release];
    foo = [[class alloc] init];
}

请注意,此处不需要使用
-retain
,因为正如我前面提到的,
+alloc
将retain计数设置为1。

不,下面是发生的情况:

-release
方法递减保留计数,然后检查它现在是否为零。如果保留计数为零,
-release
调用
[self-dealloc]
,这会导致立即释放对象。因此,根据您的示例,在发送
-retain
消息之前发送
-release
,可能会导致应用程序崩溃

根据您添加的注释,这里有一种编写代码的替代方法,我认为它可以实现您想要的功能,同时避免代码重复:

Class class = Nil;

// Decide which class (if any) to use...
switch (test)
{
    case 1: class = [A class];  break;
    case 2: class = [B class];  break;
    case 3: class = foo == nil ? Nil : [C class]; break;
    case 4: class = [D class];  break;
}

// If a class was selected, create a new instance 
// and release the previous one...
if (class != Nil)
{
    [foo release];
    foo = [[class alloc] init];
}
请注意,这里不需要
-retain
,因为正如我前面提到的,
+alloc
将retain count设置为1。

是的,在引用计数(非GC)环境中,在
填充期间,您肯定有“丢失”的风险。如果您的第一次
-release
foo
的引用计数减为0,则它将被释放。在这种情况下,继续使用
foo
是在冒险进行未定义的行为,最终你几乎肯定会为此付出代价。换句话说,这里有龙。它可能适用于您(以及您调用的任何其他框架)在
STUFF
期间,不要分配任何内存,这会超过
foo
引用的已分配实例,并且
foo
-dealoc
方法指向的实例不会更改
foo
的状态,除非释放实例变量引用并粉碎那些参考资料等等。在这种情况下,您的代码可能会像
foo
没有被释放一样工作,但这只是运气

在垃圾收集的环境中,你是安全的。由于您通过
STUFF
持有对
foo
的引用,并且
-release
-retain
在GC环境中都不是ops,因此
foo
仍然有效。

是的,在引用计数(非GC)环境中
STUFF
期间,您肯定有“丢失”的风险。如果您的第一次
-release
foo
的引用计数减为0,则它将被释放。在这种情况下,继续使用
foo
是在冒险进行未定义的行为,最终你几乎肯定会为此付出代价。换句话说,这里有龙。它可能适用于您(以及您调用的任何其他框架)在
STUFF
期间,不要分配任何内存,这会超过
foo
引用的已分配实例,并且
foo
-dealoc
方法指向的实例不会更改
foo
的状态,除非释放实例变量引用并粉碎那些参考资料等等。在这种情况下,您的代码可能会像
foo
没有被释放一样工作,但这只是运气

在垃圾收集的环境中,你是安全的。因为您持有对
foo