需要在iPhone内存管理中进行说明

时间:2011-02-15 17:33:41

标签: ios memory-management autorelease

我在iPhone内存管理方面几乎无需澄清。

以下是制定者的例子;
1)。

-(void)setValue:(NSString*)input{
[value autorelease];
value = [input retain];
}

在这个例子中,为什么我们必须使用autorelease? 我们可以使用如下吗?


if(value)
[value release];
value = [input retain];

在第一个例子中,为什么我们不应该释放input的内存 2)。 如果我使用以下声明; value

的保留计数是多少?
NSString *value;
value = @"welcome";

在上述声明之后,我正试图再设置一个值。然后会发生什么?

eg:
value = @"For testing";

3)。 2)和3)之间有什么不同?

NSString *value;
value = [input1 retain];
...
...
value = [input2 retain];// Now what is the retain count for value

4)。 如果我使用以下声明,为什么应用程序会崩溃?


NSString *value = [[[NSString alloc] init] autorelease];
...
...

提前致谢..

5 个答案:

答案 0 :(得分:2)

如果“input”与“value”完全相同,则调用[value release]可以释放该对象。因此,您必须保留新的输入值,释放旧值,然后将新值分配给ivar:

[input retain];
[value release];
value = input;

在2)和3)之后,NSString *值指向文字NSString对象,每种情况下保留计数为1,释放它可能不是一个好主意

在此代码之后:

value = [input2 retain];

value是input2对象的别名。需要注意的是对象有保留计数,变量没有。

至于你的上一个案例,

NSString *value = [[[NSString alloc] init] autorelease];

它会创建一个自动释放的空字符串。如果在自动释放实际发生后再次引用该对象,则可能会发生崩溃,因为您将引用一个不再存在的对象。

答案 1 :(得分:0)

如果在保留新值之前释放值,那么如果将相同的值设置两次,则可能会出现问题。如果调用者没有保留自己的副本,例如当他们从他们尝试设置它的同一个对象获取值时会发生这种情况,如下所示:

object.value = object.value;

该语句将导致对象在再次保留之前被释放,这可能导致内存被释放并导致保留悬空指针。通过执行自动释放,它确保将相同的指针复制到自身上将正常工作。

答案 2 :(得分:0)

1) 您将不得不进行自动释放,原因如下: 当输入是与值相同的对象时,您将释放值,它的保留计数将达到零并在您通过输入再次保留之前取消分配。 您可以使用retain来执行此操作,但必须更改代码:

-(void)setValue:(NSString*)input{
   if (value != input) {
      [value autorelease];
      value = [input retain];
   }
}

2) 我相信@“Text”将被视为常量。当您需要使用不需要任何内存管理的对象时:

NSString *value = [NSString stringWithString:@"Text"];

这将返回一个自动释放的对象。

3)在这个例子中,它不是关于值的保留计数,而是关于引用值1的两个对象的保留计数。 如果在离开该方法之前不释放input1,则会出现内存管理问题。

4)此声明应该有效。没有必要争论。你宁愿使用[NSString string]。

注意: 对于内存管理:当您使用分配新复制时,您还必须使用发布 autorelease 相同范围内的相同对象。

答案 3 :(得分:0)

我通常把我的二传手写成

- (void)setValue:(NString *)input {
    if (value != input) {
        [value release];
        value = [input retain];
    }
}

避免了输入和值都是同一个对象的问题。如果你只是在没有检查的情况下发布它,那么你可以完全释放它,下一行将尝试保留一个不再存在的对象。


但是,最好复制字符串而不是保留它们:)

答案 4 :(得分:0)

(假设你在非gc环境中工作)

1)你可以创建一个临时变量并在retain / assign之后释放temp。否则,你需要比较指针。延期发布也可能掩盖线程错误(无论你认为好坏都是......)

2)从技术上讲,NSString文字对程序的生命周期有效。即:while (1) [@"why won't i die?" release];产生无限循环。

3)使用显式retain,alloc + init,new和copy,您必须使用release或autorelease来抵消保留计数。因为你没有释放value1,静态分析可能(正确地)发现它是泄漏。由于字符串常量永远不会消失,因此这两者在这方面无法比较。

4)这个问题没有错。问题出在你的程序的其他地方。要么将其分配给ivar而不保留,要么稍后将其释放。

经常尝试使用静态分析,并尝试减少使用自动释放的程度(完全无法避免)。

这一切都不是魔术,但你可以通过不使用自动释放来至少减少许多问题的位置(或非常接近)。只要尽可能使用手动保留/释放。

最后,检查泄漏并启用NSZombies。