Lifetime of weak local variables with ARC

前端 未结 2 945
一个人的身影
一个人的身影 2020-12-18 06:45

If I have a piece of code that looks like this:

- (void)testSomething
{
  __weak NSString *str = [[NSString alloc] initWithFormat:@\"%@\", [NSDate date]];
           


        
2条回答
  •  南笙
    南笙 (楼主)
    2020-12-18 07:34

    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:

    • Create a new iOS project (Single View App using ARC and Storyboards)
    • 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.

提交回复
热议问题