[英]Need clarification in iPhone memory management
我在iPhone内存管理方面几乎无需澄清。
这是setter的一个例子;
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];
...
...
提前致谢..
如果“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];
它会创建一个自动释放的空字符串。 如果在自动释放实际发生后再次引用该对象,则可能会发生崩溃,因为您将引用一个不再存在的对象。
如果在保留新值之前释放值,那么如果将相同的值设置两次,则可能会出现问题。 如果调用者没有保留自己的副本,例如当他们从他们尝试设置它的同一个对象获取值时会发生这种情况,如下所示:
object.value = object.value;
该语句将导致该对象在再次保留之前被释放,这可能导致内存被释放并导致保留悬空指针。 通过执行自动释放,可以确保将相同的指针复制到自身上可以正常工作。
1)由于以下原因,您将不得不进行自动释放:当输入与值相同的对象时,您将释放值,它的保留计数将达到零并在您通过输入再次保留之前取消分配。 您可以使用retain来执行此操作,但您必须更改代码:
-(void)setValue:(NSString*)input{
if (value != input) {
[value autorelease];
value = [input retain];
}
}
2)我相信@“Text”将被视为常量。 当您需要一个不需要任何内存管理的对象时:
NSString *value = [NSString stringWithString:@"Text"];
这将返回一个自动释放的对象。
3)在这个例子中,它不是关于值的保留计数,而是关于引用值1的两个对象的保留计数。 当你不离开该方法之前释放输入1,你将有一个内存管理问题。
4)此声明应该有效。 没有必要争论。 你宁愿使用[NSString string]。
注:内存管理:当您使用的alloc新的或复制的 ,你还必须在同一范围内使用释放或自动释放同一个对象上。
我经常写我的二传手
- (void)setValue:(NString *)input {
if (value != input) {
[value release];
value = [input retain];
}
}
这避免了输入和值都是同一个对象的问题。 如果你只是在没有检查的情况下释放它,那么你可以完全释放它,下一行将尝试保留一个不再存在的对象。
但是,最好的做法是复制字符串而不是保留它们:)
(假设你在非gc环境中工作)
1)您可以创建一个临时变量,并在保留/分配后释放温度。 否则,你需要比较指针。 延期发布也可能掩盖线程错误(无论你认为好坏都是......)
2)从技术上讲,NSString文字对程序的生命周期有效。 那就是: while (1) [@"why won't i die?" release];
while (1) [@"why won't i die?" release];
产生无限循环。
3)使用显式retain,alloc + init,new和copy,您必须使用release或autorelease来抵消保留计数。 因为你没有释放value1,静态分析可能(正确地)发现它是泄漏。 因为字符串常量永远不会死,所以这两者在这方面无法比较。
4)这个问题没有错。 问题出在你的程序的其他地方。 要么将其分配给ivar而不保留,要么稍后将其释放。
经常尝试使用静态分析,并尝试减少使用自动释放的程度(你不能完全避免它)。
这些都不是魔术,但你可以通过不使用自动释放来至少减少许多问题的位置(或非常接近)。 尽可能使用手动保留/释放。
最后,检查泄漏并启用NSZombies。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.