ObjectiveC:使用NSString和__weak与ARC时的奇怪行为

时间:2015-07-21 03:40:36

标签: ios objective-c

第一个代码和输出:

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

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

输出:

(null), sunny

但是我将string1的声明移到text之上后,输出就不同了。这是代码:

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

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

输出:

sunny, sunny

我对不同的输出很困惑:

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

1 个答案:

答案 0 :(得分:6)

试图弄清楚对象何时被释放或者弱引用是否具有挑战性,并且通常并不能真正帮助理解。以下是您可以看到与预期不同的结果的一些原因:

  • NSString:在进行此类调查时,最好从不使用此类型。字符串文字是不朽的,它们不会被收集,即使你不期待它,你也可能有一个字符串文字。
  • 自动发布池:自动发布池实际上是ARC之前的宿醉,但它仍然存在,许多方法都返回自动释放的对象。这意味着许多物体的寿命会超出您的预期,但不会太长。然而,ARC有技巧并且可以尽早从自动释放池中删除对象,因此您可能首先认为该对象将存活更长时间然后它不会...
  • weak 引用:在前两个项目符号之后,您应该猜测,因为您可能不知道对象何时被释放,如果有的话,那么您可能没有真正的想法当weak引用变为空时。快点思考""。
  • 优化:编译器可以在优化中留有一些余地,同时保留程序的正确语义,可能会改变对象的生命周期。

如果您确实想进行这类调查,那么如果(a)使用您自己的类类型,而不是库中的任何类型,以及(b)使用@autoreleasepool { ... }块来限制生命周期,您可能会更进一步。自动发布的对象。

作为一个例子,当我在编译器上运行你的代码时,我没有得到(null),但是将第一个赋值更改为string0 = text.lowercaseString.mutableCopy确实产生了一个...找出原因是什么离开作为练习...

有一个探究的头脑和探索,这很好,但要为非显而易见的人做好准备!

HTH