简体   繁体   中英

iOS: Memory leak codes

Can someone tell me why the following code leaks memory under ARC? I tested them with Instruments and it shows me they cause a memory leak, but I don't know how to fix them ?

static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
    return [directory stringByAppendingPathComponent:key]; //leak
}

@property (nonatomic,strong) NSMutableData *postBody;

    if (![self postBody]) {
        [self setPostBody:[NSMutableData data]]; //leak
    }

Another question:The instruments shows me the " All Heap Allocations " and " All Anonymous VM " Live Bytes . And for example if an app occupies over 80M(for example), it will crash. Then 80M means All Heap Allocations or Both ?

UPDATE:

As mentioned in one of my comments below, I am now working on change non-ARC ASIHttpRequest to ARC mode. And leaks come. Take ASIInputStream for example:

+ (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest {
    ASIInputStream *theStream = [[self alloc] init]; //leak 42%
    [theStream setRequest:theRequest];
    NSInputStream *is = [NSInputStream inputStreamWithData:data]; //leak 58%
    [theStream setStream:is];
    return theStream;
}

This is a shot in the dark, but on the C function, you could try this

__attribute__((ns_returns_autoreleased))
static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
    return [directory stringByAppendingPathComponent:key]; //leak
}

Cf. Clang docs for more info. You might also try getting rid of static inline and seeing if that helps.

If you are mixing ARC and non-ARC code, then it's hard to advise you without seeing the big picture. I don't know what your skill level is, but I'd steer novices away from attempting such mixing.

I tested a piece of your code by putting it in a new Empty iOS application; looks like this:

在此处输入图片说明

Here's my complete AppDelegate implementation, which does nothing but continually run your cachePathForKey function.

#import "AppDelegate.h"

@implementation AppDelegate

static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
    return [directory stringByAppendingPathComponent:key]; //leak
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    while (YES) {
        @autoreleasepool {
            NSString *s = cachePathForKey(@"/my/fake/dir", @"key");
        }
    }

    return YES;
}

@end

I run it Xcode, Product > Profile, and when Instruments starts up, I choose Memory > Leaks. It finds no problems. You might try building up from scratch like that, and seeing if you can find problems that way.

Another technique would be to make a copy of your project (or branch; I strongly recommend version control, and particularly git ). Then start stripping out code until you get down to a very minimal bit of code that still leaks. You could then post that code somewhere; github is common, either as a small chunk -- a gist -- or as a full Xcode project.

Either way, top-down or bottom-up, it's frustrating, and laborious, like a difficult scientific discovery, or an elusive police investigation. But tackling these kind of problems with dogged determination is a huge part of being a software developer. And there's a very helpful community out here. Good luck.

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