Objective-C:弱的attritube不能按预期工作

时间:2013-01-02 04:56:08

标签: ios weak-references strong-references

  

可能重复:
  Why do weak NSString properties not get released in iOS?

我是Objective C的新手,我有一些问题,我无法回答。 我有一段用于测试__weak变量的代码(我当然使用ARC):

NSString *myString = [[NSString alloc] initWithFormat:@"John"];
NSString * __weak weakString = myString;
myString = nil; //<-- release the NSString object
NSLog(@"string: %@", weakString);

上述代码的输出符合预期,因为weakString是一个弱变量:

2013-01-02 11:42:27.481 ConsoleApp[836:303] string: (null)

但是当我将代码修改为:

NSString *myString = [[NSString alloc] initWithFormat:@"John"];
NSString * __weak weakString = myString;
NSLog(@"Before: %@", weakString); //<--- output to see if the __weak variable really works.
myString = nil;
NSLog(@"After: %@", weakString);

输出完全不符合我的预期:

2013-01-02 11:46:03.790 ConsoleApp[863:303] Before: John
2013-01-02 11:46:03.792 ConsoleApp[863:303] After: John

后一个NSLog的输出必须是(nil)而不是“John”。我试图在许多文件中搜索,但我没有找到这个案例的答案。 有人可以给出合理的解释吗?提前谢谢。

2 个答案:

答案 0 :(得分:7)

NSLog函数在自动释放池中保留传递的NSString。因此,在自动释放池耗尽之前,归零弱变量将不会归零。例如:

__weak NSString* weakString = nil;

@autoreleasepool {
    NSString* myString = [[NSString alloc] initWithFormat:@"Foo"]; // Retain count 1
    weakString = myString;         // Retain count 1
    NSLog(@"A: %@", weakString);   // Retain count 2
    NSLog(@"B: %@", weakString);   // Retain count 3
    myString = nil;                // Retain count 2
    NSLog(@"C: %@", weakString);   // Retain count 3

    NSAssert(weakString != nil, @"weakString is kept alive by the autorelease pool");
} 

// retain count 0
NSAssert(weakString == nil, @"Autorelease pool has drained.");

为什么NSLog将字符串放入自动释放池?这是一个实现细节。

您可以使用调试器或Instruments来跟踪NSString实例的保留计数。确切的保留计数并不重要,但它确实揭示了幕后发生的事情。重要的是,当自动释放池耗尽时,NSString实例将被释放。

答案 1 :(得分:0)

我认为这只是一些实现细节。你的弱变量正在被清除,但不仅仅是立即。例如,这可以按预期工作:

NSString *myString = [[NSString alloc] initWithFormat:@"John"];
NSString * __weak weakString = myString;
@autoreleasepool {
    NSLog(@"Before: %@", weakString);
    myString = nil;
}
NSLog(@"After: %@", weakString); // nil