Почему статическая утечка NSString? - PullRequest
4 голосов
/ 25 июня 2011

У меня есть следующий код для получения путей к файлам в моих iOS-приложениях:

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;
}

В консоли отладки я получаю довольно много подобных сообщений:

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

В чем проблема с кодом?(Я даже использую iOS 5 с «автоматическим» сохранением / выпуском и т. Д.)

Приветствия.

Ответы [ 4 ]

11 голосов
/ 25 июня 2011

Это сообщение появляется, когда вы автоматически высвобождаете объект в потоке, который не имеет пулов релизов в своем стеке.По умолчанию в главном потоке всегда есть пул автоматического выпуска.Он создается и управляется в функции UIApplicationMain(), которая обычно вызывается функцией main () вашего приложения.Тем не менее, дополнительные потоки, которые вы создаете (с performSelectorInBackground: или NSThread), не имеют пула автоматического освобождения, если вы не поместите его туда специально, поэтому любые автоматически выпущенные объекты в этом фоновом потоке не имеют пула для их последующего освобождения и будут простоутечка.

Если вы добавляете что-то в фоновый поток, первое, что вы должны сделать, это создать пул авто-релиза.Под ARC используйте новую конструкцию @autoreleasepool, чтобы сделать это.

1 голос
/ 25 июня 2011

Вы пытались запустить один и тот же код в не-ARC приложении? Сделав это, вы можете подтвердить, является ли это проблемой ARC или реальной ошибкой в ​​рамках. ARC все еще незрелый, Apple неоднократно заявляла, что это еще не сделано, и определенно есть ошибки.

Если вас беспокоит количество создаваемых видимых объектов автоматического выпуска, используйте конструкцию @autoreleasepool {...} вокруг рассматриваемого кода. Это значительно более эффективно , чем NSAutoreleasePool, который вы все равно не можете создать в коде ARC.

0 голосов
/ 25 июня 2011

Это происходит, если вы удалили вызовы NSAutoreleasePool в файле main.m или если этот код выполняется в отдельном потоке.Поскольку вы не можете использовать NSAutoreleasePool с ARC, вы должны поместить код потока в блок @autoreleasepool

0 голосов
/ 25 июня 2011

Я не думаю, что это настоящая утечка.Apple несколько раз обсуждала это на симуляторе, это известная ложная ошибка в том, как библиотеки симулятора работают с NSAutoReleasePool, но недостаточно значительная, чтобы гарантировать исправление, так как у вашего Mac значительно больше памяти, чем у устройства.На WWDC они упомянули, что есть несколько мест, где NSZombie не справляется с авто-выпуском правильно, но я не могу вспомнить, в какой сессии это происходило. Если вы не замечаете утечки для этих объектов в инструментах, вам не стоит беспокоитьсяЭто.Если вы заметили утечку при использовании инструментов, подайте отчет об ошибке .

. Не создавайте пул автоматического освобождения вокруг вашего метода только потому, что он выглядит как утечка.В ARC это просто не сработает, и, если вы не изменили функцию main () своего приложения, у вас есть пул авто-релиза, включающий все .Создание дополнительного пула автоматического выпуска без данных профилирования, указывающих на серьезное давление памяти после вызова этого метода, фактически ухудшит производительность вашего приложения.

...