Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does static NSString leak?

I have the following code to retrieve file paths on my iOS Apps:

static const NSString * fullPathFromRelativePath(NSString *relPath)
{
    // do not convert a path starting with '/'
    if(([relPath length] > 0) && ([relPath characterAtIndex:0] == '/'))
        return relPath;

    NSMutableArray *imagePathComponents = [NSMutableArray arrayWithArray:[relPath pathComponents]];

    NSString *file = [imagePathComponents lastObject];    
    [imagePathComponents removeLastObject];

    NSString *imageDirectory = [NSString pathWithComponents:imagePathComponents];

    NSString *fullpath = [[NSBundle mainBundle] pathForResource:file
                                                         ofType:NULL
                                                    inDirectory:imageDirectory];
    if (!fullpath)
        fullpath = relPath;

    return fullpath;    
}

static const char * fullCPathFromRelativePath(const char *cPath)
{
    NSString *relPath = [NSString stringWithCString:cPath encoding:NSUTF8StringEncoding];
    const  NSString *path = fullPathFromRelativePath(relPath);
    const char *c_path = [path UTF8String];
    return c_path;
}

static const char * relativeCPathForFile(const char *fileName)
{        
    NSString *relPath = [NSString stringWithCString:fileName encoding:NSUTF8StringEncoding];        
    const NSString *path = fullPathFromRelativePath(relPath);
    const char *c_path = [[path stringByDeletingLastPathComponent] UTF8String];    
    return c_path;
}

I'm getting quite a few messages like this in the debug console:

objc[4501]: Object 0x6e17060 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[4501]: Object 0x6e12470 of class NSPathStore2 autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[4501]: Object 0x6e12580 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

What's the problem with the code ? ( I'm even using iOS 5 with "automated" retain/release, etc )

Cheers.

like image 439
Goles Avatar asked Dec 13 '22 11:12

Goles


1 Answers

This message shows up when you autorelease an object on a thread that does not have any release pools in its stack. By default, there is always an autorelease pool on the main thread. It's created and managed within the UIApplicationMain() function that is usually called by your app's main() function. However, additional threads you create (with performSelectorInBackground: or NSThread) do not have an autorelease pool in place unless you specifically put one there, so any autoreleased objects on that background thread have no pool to release them later, and will just leak.

If you're kicking something off to a background thread, the first thing you should do is create an autorelease pool. Under ARC, use the new @autoreleasepool construct to do that.

like image 119
BJ Homer Avatar answered Dec 28 '22 13:12

BJ Homer