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