#iphone #ios #memory #memory-leaks
#iPhone #iOS #память #утечки памяти
Вопрос:
Я новичок в разработке iPhone ObjectiveC. Я получаю утечки памяти, когда запускаю следующий метод.
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:@"dbname.sqlite"];
}
и я обнаружил, что если я урежу это только до следующего… она все еще протекает
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
return nil;
}
итак, я попытался освободить переменную paths следующим образом, из-за чего все еще происходит утечка памяти.
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
[paths release];
return nil;
}
Чтобы обнаружить утечку, я запускаю ее в профилировщике со следующим циклом:
for (int iLoop = 0; iLoop < 30; iLoop ) {
NSString *dbPath = [self getDBPath];
[dbPath release];
sleep(1);
}
Объем памяти, связанный с NSPathStore2 и NSArrayM, продолжает расти.
Любые предложения о том, что я могу делать неправильно? Спасибо!
Комментарии:
1. Что указывает на утечку? Первый метод, который у вас есть, полностью разумен и именно то, что вы должны делать.
2. запускаем его в профилировщике, внутри цикла. Я только что обновил исходный вопрос выше, добавив более подробную информацию о цикле.
3.
NSZombieEnabled
все еще активен? Или нет NSAutoreleasePool, потому что это выполняется в фоновом режиме?4. У меня нет информации о фактическом профилировании, но повторите свой тест: вам не следует выпускать строку, если вы нигде ее не сохраняете, и пул авторелиза не будет исчерпан до завершения цикла событий. Тем не менее, не уверен, почему вы видите утечку.
5. я думаю, что была бы какая-то другая причина, потому что эти строки не протекают со мной.
Ответ №1:
Ваш код для getDBPath в порядке, но, вероятно, он вызывается из контекста без какого-либо пула авторелиза.
Исправьте это, выделив свой собственный пул в циклическом коде:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (int iLoop = 0; iLoop < 30; iLoop ) {
NSString *dbPath = [self getDBPath];
// [dbPath release]; // do not release! dbPath will be autoreleased
sleep(1);
}
[pool drain];
Ответ №2:
вы не должны освобождать объект, которым вы не владеете. В вашем случае вы пытаетесь освободить память, которой вы не владели. Как и в «путях», всегда ссылаются на память, выделяемую и управляемую «NSSearchPathForDirectoriesInDomains» . Таким образом, вы не должны освобождать память в этом случае. Установите общее правило, если вы не выделяете память самостоятельно, вам не следует вызывать освобождение памяти для каждого указателя, который вы используете в своей программе. Надеюсь, это поможет!