简体   繁体   中英

Xcode static analyzer doesn't detect leak?

I've put together the following minimal example where the Xcode (4.5.2) static analyzer apparently doesn't detect a leak, in order to verify some observations I have made about the static analyzer:

#import <Foundation/Foundation.h>

@interface Foo : NSObject {
    NSArray *array;
}
@property (nonatomic, retain) NSArray *array;
- (void)bar;
@end

@implementation Foo
@synthesize array;
- (void)bar
{
    // Shouldn't the static analyzer flag this as a leak?
    array = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}
@end

int main(int argc, const char *argv[])
{
    @autoreleasepool {
        Foo *foo = [[Foo alloc] init];

        [foo bar];
        [foo bar];
        [foo bar];

        [foo release];
    }

    return 0;
}

Calling bar repeatedly will leak NSArray instances, if I am not mistaken. bar creates an NSArray instance with a +1 retain count when its name implies it wouldn't. The instance previously assigned to the array instance variable is leaked as it is never released.

What really concerns me, however, is that I read somewhere that ARC is basically using the same algorithm as the static analyzer. Does this mean that this code would leak under ARC, too? Or does ARC treat all instance variables as strong by default, even without a __strong qualifier or a corresponding (strong) property?

without arc:

It doesn't detect the leak because array is an instance variable.So isn't considered a leak to assign it to an object that has a retain count to 1, because the instance variable array is still accessible and valid.
Even if you call multiple times that method, the static analyzer isn't just enough smart to know that array was pointing to a retained variable.
The static analyzer just helps you to know when an object is leaked in a single method.
But try to change the method that way:

- (void)bar
{
    // Shouldn't the static analyzer flag this as a leak?
    NSArray* array2 = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}

That will be detected by the static analyzer.

About ARC

With ARC this code wasn't leaking because when you say array= , it's like if you:

  1. release array:
  2. retain the newly created object;
  3. Assign it to the instance variable.

So I'd suggest to turn to ARC if you can.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM