在 iOS 中了解 ARC

Understanding ARC in iOS

我写了这段代码来测试 ARC。我将字符串 s2 设置为 weak 并为其分配 s1 的值。然后,我将 s1 设置为 nil。我假设因为这个后台块是在稍后执行的,所以 s2 到那时已经被释放了。但是,当我 运行 这段代码时,NSLog 仍然将 s2 的值打印为“123”。有人可以向我解释为什么会这样吗?

- (void)testARC {
    NSString *s1 = [NSString stringWithFormat:@"123"];
    __weak NSString *s2 = s1;
    s1 = nil;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        // what will NSLog print?
        NSLog(@"s2 = %@", s2);
    });
}

两个注意事项:

  1. 您正在创建一个自动释放对象,该对象在池耗尽之前不会被释放。如果您创建一个非自动释放对象(或使用您自己的自动释放池),您将看不到该行为,例如:

    NSString *s1 = [[NSString alloc] initWithFormat:@"123"];
    __weak NSString *s2 = s1;
    s1 = nil;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        // what will NSLog print?
        NSLog(@"s2 = %@", s2);
    });
    
  2. 您应该始终警惕使用 NSString 评估内存行为。在这种情况下,我认为这并不重要,但在其他情况下 NSString 会进行各种可能影响行为的优化和缓存。我建议使用 NSObjectNSObject 子类进行测试。