Search code examples
ios9nsautoreleasepool

autoreleasePool is different in iOS 9?


__weak NSString *string_weak_ = nil;

- (void)viewDidLoad {
    [super viewDidLoad];
    @autoreleasepool {
        NSString *string = [NSString stringWithFormat:@"hello"];
        string_weak_ = string;
    }
    NSLog(@"string: %@", string_weak_);
}

`

string: (null) // in iPhone(iOS 8.1) simulator
string: hello  // in iPhone(iOS 9.0) simulator

I run this code in iPhone(8.1) and iPhone(9.0) simulator.The result is different. I wonder what happened?


Solution

  • Both results are reasonable. The result is implementation-dependent, depending on whether someone else has a reference to the string object returned by the [NSString stringWithFormat:] or something, and whether it is even a dynamically-allocated object at all, vs. a statically-allocated object.

    String literals evaluate to pointers to statically-allocated objects that exist for the lifetime of the program, and are not memory managed by reference counting. Certain methods, e.g. [NSString stringWithString:], when given an immutable string, simply return the given string, and will not created a new string object, as an optimization.

    Here, [NSString stringWithFormat:] is used. It's also possible for it to simply return the given format string object, in the case where it's an immutable string and there are no format specifiers. I haven't tested this personally, but perhaps this optimization was added into [NSString stringWithFormat:] between OS versions.

    Anyway, whether such an optimization exists is implementation-dependent and shouldn't matter to us, because we should never rely on things like whether an object is dynamically-allocated or statically-allocated, or whether there are additional references to it or not.