2015-07-21 63 views
6

第一代码和输出:的ObjectiveC:使用的NSString和__weak当奇怪的行为与ARC

NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
__weak NSString *string1; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

输出:

(null), sunny 

但经过我移动声明的string1text以上,输出是不同的。下面是代码:

__weak NSString *string1; 
NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

输出:

sunny, sunny 

我很困惑与不同的输出:

  • 为什么string0string1是在第一种情况有什么不同?
  • 为什么第二种情况的输出与第一种情况不同?
+0

更为奇怪的是,第一种方案给出正确的输出,如果你通过保持一个断点运行,然后通过行执行行。但是,如果你删除断点,它会给出'null'。 – Gandalf

回答

6

试图找出一个对象被释放的时间或一个弱引用无效可能是具有挑战性的,而且往往并不能真正帮助理解。这里有一些原因,你可以看到不同的结果比预期:

  • NSString:这是最好从未做这些实物调查时使用此类型。字符串文字是不朽的,它们不被收集,即使你不期望也可能有字符串文字。
  • 自动发布池:自动发布池实际上是ARC之前的宿醉,但它仍然存在,许多方法返回自动发布的对象。这意味着许多物体的寿命将超过您的预期,但不会太长。但ARC有技巧,并可以尽早从自动释放池中删除对象,所以你可能会首先认为对象会活得更长,然后它不会...
  • weak引用:在前两个子弹之后,你应该猜测当一个对象被释放时你可能没有真正的想法,如果有的话,那么当weak引用被忽略时你可能没有真正的想法。只是想“很快”。
  • 优化:编译器可以在优化中存在一些余地,它在保留程序的正确语义的同时,可能会改变对象的生存期。

如果你想运行这些类型的调查,那么你可能会得到进一步的,如果(一)使用自己的类类型,而不是从图书馆的任何及(b)使用@autoreleasepool { ... }块来限制汽车的寿命释放物体。作为一个例子,当我在编译器上运行你的代码时,我使用的是我没有得到的(null),但是将第一个任务改为string0 = text.lowercaseString.mutableCopy确实产生了一个......弄清楚为什么只剩下一个练习...

有一个探究的心灵和探索,这是好的,但为非显而易见的准备!

HTH