If I have a piece of code that looks like this:
- (void)testSomething
{
__weak NSString *str = [[NSString alloc] initWithFormat:@\"%@\", [NSDate date]];
The lifetime of a local weak variable is not guaranteed at all. If the object that the variable points to is deallocated, the weak variable will point to nil afterwards.
If you have a weak reference to an object that you got via a method that does not return a retained object, it is not safe to assume that this object lives until the method exits. If you want to make sure that the object survives, use a strong reference.
Here is an example that shows that a non-retaining method's return value is not guaranteed to end up in the autorelease pool:
Add this method to the AppDelegate.m:
+ (id)anObject
{
return [[NSObject alloc] init];
}
Replace -application:didFinishLaunchingWithOptions::
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
__weak id x = [AppDelegate anObject];
NSLog(@"%@", x);
return YES;
}
Important: Now set the Optimization level for Debug to -Os.
In this example, +[AppDelegate anObject] acts like a convenience constructor, but you will see (null) logged if you execute it on a device with -Os optimization. The reason for that is a nifty ARC optimization that prevents the overhead of adding the object to the autorelease pool.
You may have noticed that I switched to not using a library method like +[NSString stringWithFormat:]. These seem to always put objects in the autorelease pool, that may be for compatibility reasons.