#iphone #objective-c #cocoa-touch #ios4 #nsarray
#iPhone #objective-c #cocoa-touch #ios4 #nsarray
Вопрос:
У меня есть код, который показывает утечки в инструментах. Он показывает утечки, в которых я инициализирую arrayDetPerformance
содержимое arrayDetail
Если я выпускаю свой arrayDetail
, то мое приложение вылетает.
Что может быть не так?
Вот код:
NSDictionary *finalResult = [extractUsers JSONValue];
// NSLog(@" Stamp-16 : %@",[NSDate date]);
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
// NSLog(@"Data is : %@",array1);
// NSLog(@" Stamp-17 : %@",[NSDate date]);
//NSLog(@"Final Value is : %@",[[allUsers objectAtIndex:0] valueForKey:@"password"]);
//[self setUserData:allUsers];
//[tblView reloadData];
[responseString release];
[request release];
}
//sleep(0.3);
//[inProgressIndicator stopAnimating];
[fileContents release];
//Release all the allocated data
[json release];
//label.text = @"Finish";
// NSLog(@" Stamp-19 : %@",[NSDate date]);
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
//NSLog(@"Array2 : %d",[array2 retainCount]);
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
chartPoints= [arrayDetPerformance valueForKey:@"Points"];
NSLog(@"Chart Points: %@",chartPoints);
[def setObject:chartPoints forKey:@"yarray"];
[def setObject:@"YES" forKey:@"flagThumb"];
//array1 = [[NSMutableArray alloc] initWithObjects:@"New",@"Table",@"View",nil];
//[self.Dettable reloadData];
//sNSFileManager *fileManager = [NSFileManager defaultManager];
//[array2 release];
NSLog(@"ArrayDEtPerfomance : %d",[arrayDetPerformance retainCount]);
NSLog(@"array2 : %d",[arrayDetail retainCount]);
if([chartPoints count]>0)
{
PlotItem *plotItem = [[PlotGallery sharedPlotGallery] objectAtIndex:0];
[plotItem imageHive:Fund];
}
//[arrayDetail release];
}
В строке отображается утечка памяти
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
Также я не понимаю, почему количество сохранений напрямую меняется с 0 на 2 в приведенном ниже коде:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
Что может быть не так?
Комментарии:
1. Как
arrayDetPerformance
объявляется? Является ли это свойством?2. Комментарий со стороны: AFAIK, вы никогда не должны полагаться на значение [yourObj retainCount] во время выполнения… Сохранить количество может быть полезно только в инструментах.
3. @Ник Уивер: Да, это NSMutableArray со свойством (неатомный, сохранять) и он синтезирован. Что может быть не так?
4. Вы настраиваете
arrayDetPerformance
так, как показано в вашем коде, или вы действительно используетеself.arrayDetPerformance = ...
?5. -retainCount никогда не может вернуть ноль .
Ответ №1:
Это показывает утечку, потому что вы выделяете arrayDetPerformance
, а затем не выпускаете его. Вот так просто. По крайней мере, это то, что мы можем сказать из кода, который вы нам показываете.
Что касается остального, никогда не используйте retainCount
для устранения проблем с памятью! Вы должны понимать простые правила управления памятью и следовать им, ничего больше. Поскольку вы не знаете, что делает базовый код Apple, вы не можете полагаться на количество сохранений объекта.
Что касается вашего вопроса, касающегося этого кода:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
Вы присваиваете совершенно другой объект arrayDetail
, поэтому совершенно бессмысленно сравнивать какие-либо свойства arrayDetail
до и после присвоения. Количество сохранений может быть повсюду, и это вам ничего не скажет.
У меня создается впечатление, что вы действительно не знаете, что вы здесь делаете. Вам следует читать правила управления памятью снова и снова, пока вы не поймете их полностью.
Комментарии:
1. @PARTH: так что, может быть, когда вызывается dealloc и пытается освободить arrayDetPerformance еще до того, как вы его используете, поэтому он никогда не инициализировался / выделялся?
Ответ №2:
retainCount
это не поможет вам отладить вашу проблему (на самом деле это почти никогда не будет иметь отношения к отладке, так что лучше забудьте, что это вообще есть).
Не выпускайте arrayDetail
, поскольку оно вам не принадлежит. Проблема в arrayDetPerformance
. Вы выделяете объект в этой строке, и он нигде не выпускается. Возможно, вы делаете это в другом месте своего кода, но если это не так, отправьте ему release
, когда закончите его использовать.
Редактировать
Если вы освобождаете arrayDetPerformance
в своем dealloc
методе, я предполагаю, что это переменная экземпляра? В этом случае вы не можете предположить, что он еще не указывает на объект, поэтому вы должны отправить ему release
перед назначением его новому объекту.
В качестве альтернативы, если оно настроено как свойство, просто используйте self.arrayDetPerformance = ...
, которое позаботится об управлении памятью за вас.
Комментарии:
1. Я уже освобождаю свой arrayDetPerformance в своем методе dealloc, так что еще может быть не так?
Ответ №3:
Не вызывайте retainCount
retainCount
бесполезно. Абсолютное количество сохраняемых объектов является деталью реализации. Правило простое; если вы вызываете сохранение чего-либо, вы должны вызвать его освобождение, когда закончите с этим. Конец истории.
В документации по управлению памятью это полностью обсуждается.
Во-первых, retainCount
может никогда не возвращать ноль. Единственный раз, когда вы получите ноль, это если вы случайно отправили сообщение nil
. Это:
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 0
arrayDetail = [[finalResult objectForKey:@"Detail"]
NSLog(@"Array2 : %d",[arrayDetail retainCount]); //RETAIN COUNT IS 2
Вы заставляете arrayDetail
указывать на другой объект во второй строке. Таким образом, нет связи между количеством сохранений до / после этой строки.
Когда утечки сообщают вам, что утечка происходит в определенной строке, подобной этой…
arrayDetPerformance = [[NSMutableArray alloc] initWithArray:arrayDetail];
… это говорит вам, что указанный объект, выделенный в этой строке, был утечен. Это не говорит вам, что именно эта строка была причиной утечки. Утечка, скорее всего, вызвана тем, что вы либо передержали его где-то в другом месте, либо забыли выполнить утечку.
В нескольких комментариях вы сказали, что «освобождаете [что-то] в своем dealloc». Покажите реализацию вашего метода освобождения.
Комментарии:
1. Я почти искал другой ваш ответ, чтобы вырезать и вставить этот первый абзац ! 🙂
Ответ №4:
[Выпуск arrayDetPerformance]; не записан в вашем коде;
Итак, это показывает утечку памяти.