Objective-C对象在被释放后存在于内存中

gui*_*eak 2 memory-management objective-c ios

我正在学习Objective-c内存管理(没有ARC),我遇到了一些常见的问题.这里曾提到过几次,所以我不是在问你"究竟是什么!?"而是"我能理解正确吗?"

问题:

文件说:

- (NSString *)fullName {

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

                                          self.firstName, self.lastName] autorelease];

    return string;

}
Run Code Online (Sandbox Code Playgroud)

您拥有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]);
Run Code Online (Sandbox Code Playgroud)

-

 Output:
    1) Address in method = 0x100002a50
    2) Address in method = 0x100002a50
    String is: [returned String] // <--
    3) Address in main = 0x100002a50
Run Code Online (Sandbox Code Playgroud)

所以,如果我理解得很好,问题是,很难预测何时会释放出准确的内存?或者实际上,内存中的特定位置仅被标记为"已释放",而这就是全部......我是对的吗?

Nik*_*uhe 7

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

在这种情况下,您将从文字中分配一个对象(永远不会被取消分配).因为新初始化的对象是不可变对象的副本,所以初始化器只返回文字(再次,永远不会被取消分配).

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

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

所以,如果我理解得很好,问题是,很难预测何时会释放出准确的内存?

好吧,对象生命周期是完全确定的(当不使用已弃用的Mac OS X垃圾收集器时).唯一的问题是自动释放池:你通常不知道,如果一个对象会被自动释放,因此,如果您生活无法进行任何猜测比你想象的.