2

我正在学习objective-c 内存管理的东西(没有ARC),我遇到了一些常见问题。这里提到了几次,所以我不是问你“到底是什么!?”,而是“我理解正确吗?”

问题:

文档说:

- (NSString *)fullName {

    NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",

                                          self.firstName, self.lastName] autorelease];

    return string;

}

你拥有 alloc 返回的字符串。要遵守内存管理规则,您必须在丢失对它的引用之前放弃对字符串的所有权。但是,如果您使用 release,则字符串将在返回之前被释放(并且该方法将返回无效对象)。使用自动释放,您表示您想要放弃所有权,但您允许方法的调用者在释放之前使用返回的字符串。

所以让我们试试:

// Method defined in one on my class:
-(NSString*) returnString {
    NSString* str = [[NSString alloc] initWithString:@"returned String"]; 
    NSLog(@"1) Address in method = %p", [str self]);
    [str release];
    NSLog(@"2) Address in method = %p", [str self]);
    return str; 
 }

// In main: 
        NSString* str = [myObject returnString];
        NSLog(@"String is: [%@]", str);
        NSLog(@"3) Address in main = %p", [str self]);

-

 Output:
    1) Address in method = 0x100002a50
    2) Address in method = 0x100002a50
    String is: [returned String] // <--
    3) Address in main = 0x100002a50

所以,如果我理解得很好,问题是,很难预测什么时候会释放内存?或者实际上,内存中的特定位置仅被标记为“释放”,仅此而已……我说的对吗?

4

2 回答 2

7

NSString在许多情况下避免分配/释放非常聪明。这使得在 Objective C 中测试释放和学习内存管理语义是一个非常糟糕的选择。

在这种情况下,您正在从文字分配一个对象(永远不会被释放)。因为新初始化的对象是不可变对象的副本,所以初始化器只会返回字面量(同样,它永远不会被释放)。

例如,您应该使用NSObject或自定义派生类来测试释放。

另一个很大的帮助是启用僵尸,因为这可以确保您立即注意到对已释放对象的第一次访问。

所以,如果我理解得很好,问题是,很难预测什么时候会释放内存?

好吧,对象的生命周期是完全确定的(当不使用已弃用的 Mac OS X 垃圾收集器时)。唯一的问题是自动释放池:您通常不知道一个对象是否被自动释放,因此您无法猜测它的寿命是否您预期的长。

于 2013-03-11T10:20:46.423 回答
0
NSString *str1 =@"parag";
NSString*str2=[[NSString alloc] initWithString:@"parag"];
NSLog(@"%p %p", str1, str2); //str1 and str2 both are same  
  //  0x100002098 0x100002098

这与内部优化有关。你必须释放str2。

注意:这依赖于编译器和 initWithString: 方法的未记录和未保证的行为。两者都可能随时改变。

于 2013-03-11T10:52:00.570 回答