简体   繁体   English

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

[英]Need clarification in iPhone memory management

I need few clarification in iPhone memory management. 我在iPhone内存管理方面几乎无需澄清。

Here is an example for setters; 这是setter的一个例子;
1). 1)。

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

In this example, why we have to use autorelease? 在这个例子中,为什么我们必须使用autorelease? Can we use like as follows? 我们可以使用如下吗?


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

In the first example, Why we should not release the memory for input 在第一个例子中,为什么我们不应该释放内存以进行input
2). 2)。 If I use following statement; 如果我使用以下声明; what is the retain count for value 什么是value的保留计数

NSString *value;
value = @"welcome";

After the above statement, just I am trying to set one more value. 在上面的陈述之后,我正试图再设置一个值。 Then what will happen? 然后会发生什么?

eg:
value = @"For testing";

3). 3)。 What is the different between 2) and 3)? 2)和3)有什么不同?

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

4). 4)。 If I use following statement, why the app is getting crash? 如果我使用以下声明,为什么应用程序崩溃?


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

Thanks in advance.. 提前致谢..

If "input" is the exact same object as "value" then calling [value release] could dealloc the object. 如果“input”与“value”完全相同,则调用[value release]可以释放该对象。 So you must retain the new input value, release the old value, then assign the new value to the ivar: 因此,您必须保留新的输入值,释放旧值,然后将新值分配给ivar:

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

After each of 2) and 3), the NSString *value points to a literal NSString object, the retain count will be 1 in each case, and releasing it is probably not a good idea 在2)和3)中的每一个之后,NSString *值指向文字NSString对象,每种情况下保留计数将为1,并且释放它可能不是一个好主意

After this code: 在这段代码之后:

value = [input2 retain];

value is an alias to the input2 object. value是input2对象的别名。 The thing to realize is that objects have retain counts, variables do not. 要实现的是对象有保留计数, 变量没有。

As for your last case, 至于你的最后一个案例,

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

It creates an autoreleased empty string. 它会创建一个自动释放的空字符串。 If you reference that object again once the autorelease actually happens, you may get a crash because you'll be referring to an object that doesn't exist any more. 如果在自动释放实际发生后再次引用该对象,则可能会发生崩溃,因为您将引用一个不再存在的对象。

If you release a value before you retain the new value then you can have problems if the same value is being set twice. 如果在保留新值之前释放值,那么如果将相同的值设置两次,则可能会出现问题。 This happens if the caller hasn't retained their own copy, such as when they get the value from the same object they try to set it on, like this: 如果调用者没有保留自己的副本,例如当他们从他们尝试设置它的同一个对象获取值时会发生这种情况,如下所示:

object.value = object.value;

That statement will cause the object to be released before it's retained again which could lead to the memory being deallocated and result in a dangling pointer being retained. 该语句将导致该对象在再次保留之前被释放,这可能导致内存被释放并导致保留悬空指针。 By doing the autorelease it ensures that copying the same pointer onto itself will work correctly. 通过执行自动释放,可以确保将相同的指针复制到自身上可以正常工作。

1) You will have to do autorelease because of the following: When input is the same object as value and you will release value it's retain count will reach zero and get deallocated before you can retain it again though the input. 1)由于以下原因,您将不得不进行自动释放:当输入与值相同的对象时,您将释放值,它的保留计数将达到零并在您通过输入再次保留之前取消分配。 You can do it with retain but you have to change your code: 您可以使用retain来执行此操作,但您必须更改代码:

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

2) I believe @"Text" will be treated as a constant. 2)我相信@“Text”将被视为常量。 When you want a object which you do not want any memory management with use: 当您需要一个不需要任何内存管理的对象时:

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

This will return an autoreleased object. 这将返回一个自动释放的对象。

3) In this example it is not about the retain count of value, but about the retain count of both objects where value one is referenced to. 3)在这个例子中,它不是关于值的保留计数,而是关于引用值1的两个对象的保留计数。 When you dont release input1 before you leave that method, you will have a memory management problem. 当你不离开该方法之前释放输入1,你将有一个内存管理问题。

4) This statement should work. 4)此声明应该有效。 No points to argue. 没有必要争论。 You rather use [NSString string]. 你宁愿使用[NSString string]。

Note: For memory management: when you use alloc new or copy , you also have to use release or autorelease on the same object in the same scope. 注:内存管理:当您使用的alloc新的复制的 ,你还必须在同一范围内使用释放自动释放同一个对象上。

I usually write my setters as 我经常写我的二传手

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

which avoids the problem of input and value both being the same object. 这避免了输入和值都是同一个对象的问题。 If you just release it without checking then you might completely free it and the next line will try to retain an object that doesn't exist anymore. 如果你只是在没有检查的情况下释放它,那么你可以完全释放它,下一行将尝试保留一个不再存在的对象。


However, it's best practice to copy strings instead of retaining them :) 但是,最好的做法是复制字符串而不是保留它们:)

(assuming you're working in a non-gc env) (假设你在非gc环境中工作)

1) you can create a temporary variable and release the temp after the retain/assign. 1)您可以创建一个临时变量,并在保留/分配后释放温度。 otherwise, you'd need to compare the pointers. 否则,你需要比较指针。 deferred release may also mask threading errors (whether you consider that good or bad is...) 延期发布也可能掩盖线程错误(无论你认为好坏都是......)

2) technically, the NSString literals are valid for the life of your program. 2)从技术上讲,NSString文字对程序的生命周期有效。 that is: while (1) [@"why won't i die?" release]; 那就是: while (1) [@"why won't i die?" release]; while (1) [@"why won't i die?" release]; yields an infinite loop. 产生无限循环。

3) with explicit retain, alloc+init, new, and copy, you must counterbalance the retain count using release or autorelease. 3)使用显式retain,alloc + init,new和copy,您必须使用release或autorelease来抵消保留计数。 since you did not release value1, the static analysis may (correctly) spot that as a leak. 因为你没有释放value1,静态分析可能(正确地)发现它是泄漏。 since the string constants never die, the two aren't comparable in this regard. 因为字符串常量永远不会死,所以这两者在这方面无法比较。

4) there's nothing wrong with that staement. 4)这个问题没有错。 the problem lies elsewhere in your program. 问题出在你的程序的其他地方。 either you are assigning it to an ivar without retaining, or releasing it later. 要么将其分配给ivar而不保留,要么稍后将其释放。

try using static analysis often, and try reducing how much you use autorelease (you can't avoid it entirely). 经常尝试使用静态分析,并尝试减少使用自动释放的程度(你不能完全避免它)。

none of this is magic, but you can at least reduce the location of many problems to the callsites (or very close) by not using autorelease all over the place. 这些都不是魔术,但你可以通过不使用自动释放来至少减少许多问题的位置(或非常接近)。 just use manual retain/release where possible. 尽可能使用手动保留/释放。

lastly, check for leaks and run with NSZombies enabled. 最后,检查泄漏并启用NSZombies。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM