#cocoa-touch #xcode4 #ios4
#cocoa-touch #xcode4 #ios4
Вопрос:
Я пытался устранить утечки памяти в своем приложении, но обнаружил, что при использовании alloc NSBundle в цикле for это приводит к утечке памяти.
вот мой код:-
in my class myFeed.m
for(int i = 0; i<20; i )
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
NSDictionary *temp = (NSDictionary*)[topData objectAtIndex:i];
NSString *iconName = [temp objectForKey:@"feed_source"];
NSString *imageName;
TimeLineGrid *grid = [[TimeLineGrid alloc]initWithNibName:@"TimeLineGrid" bundle:[NSBundle mainBundle]];
CGRect frame = grid.view.frame;
if([iconName isEqualToString:@"Youtube"])
imageName = [[NSBundle mainBundle]pathForResource:@"Youtube" ofType:@"png"];;
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
frame.size=CGSizeMake(130, 130);
}
else
{
frame.size = CGSizeMake(180, 180);
}
[grid setDelegate:self];
if (isConditionTrue)
{
x = x - 200 - topFactor;
}
else
x = x - frame.size.width;
if (x < 0)
{
x = 0;
}
frame.origin.x = x;
frame.origin.y = y;
grid.view.frame = frame;
grid.view.tag = tagCount;
if ([temp objectForKey:@"feed_item_nid"])
{
[tagToNIDMap addObject:[temp objectForKey:@"feed_item_nid"]];
}
if ([(NSString*)[temp objectForKey:@"feed_source"]isEqualToString:@"Youtube"])
{
[grid.webView loadHTMLString:[self getYoutubeCode:(NSString*)[temp objectForKey:@"feed_item_url"] :grid.webView.frame] baseURL:nil];
}
else
{
NSString * str = [[WebServiceController Initialize]parseHTMLData:[temp objectForKey:@"feed_item_body"] : @"//img"];
NSURL * url = [NSURL URLWithString:str];
NSURLRequest * req = [NSURLRequest requestWithURL:url];
[grid.webView loadRequest:req];
}
//[grid.view addSubview:grid.webView];
tagCount ;
[grid setHome:frame];
grid.dict = (NSDictionary*)[topData objectAtIndex:i];
// grid.icon.frame=CGRectMake(grid.view.frame.origin.x, grid.view.frame.origin.y-20,grid.icon.frame.size.width,grid.icon.frame.size.height)
grid.icon.image = [UIImage imageNamed:imageName];
grid.detail.text = [temp objectForKey:@"feed_item_title"];
[scroll1 addSubview:grid.view];
[imageName release];
[grid release];
[pool release];
}
}
myGrid — это еще один класс с .xib, который я пытаюсь загрузить в классе myFeed. но если в конце цикла я добавляю [grid release]
, то можно увидеть представление myGrid, но UIWebView, присутствующий в myGrid, не отображает его данные. И инструмент также показывает утечку памяти в строке :
myGrid *grid = [[myGrid alloc]initWithNibName:@"myGrid" bundle:[NSBundle mainBundle]];
что я здесь делаю не так…
Комментарии:
1. Куда вы вставили
[grid release]
? Это необходимо2. я добавил код [освобождения сетки]
Ответ №1:
Вы ничего не делаете со всеми этими myGrid
объектами (кстати, имена классов должны начинаться с заглавной буквы). Ваш цикл создает контроллер представления, загружает что-то в его webView
свойство, а затем освобождает его, что бессмысленно.
Я предполагаю, что вы что-то делаете grid
после завершения этого цикла — что это? Если вам действительно нужно 20 разных myGrid
объектов, то вам нужно добавить их в массив или что-то еще во время вашего цикла, потому что в данный момент вы просто перезаписываете значение grid
каждого процесса вашего цикла. Если вы удалите инструкцию release, то myGrid
в конце цикла у вас будет один объект и 19 пропущенных экземпляров из других проходов.
Если вам нужен один grid
объект, создайте его до начала цикла, но, похоже, в итоге получится только один объект, который настроен так, как вы его настроили во время последней итерации цикла.
Обновить
Хорошо, теперь, когда вы включили свой полный код, он немного понятнее. Вам нужно следить за каждым grid
объектом. Создайте NSMutableArray перед циклом for (вероятно, это должно быть свойством любого объекта, в котором находится этот код):
self.gridArray = [NSMutableArray array];
for (... // your loop here
Внутри цикла, прежде чем освободить grid, добавьте следующее:
[self.gridArray addObject:grid];
[grid release];
Это предотвращает потерю ссылки на каждый grid
объект, кроме последнего, и останавливает утечку памяти в этом коде. Позже вы можете освободить или изменить объекты в своем gridArray
по своему усмотрению.
Комментарии:
1. Да, если я не выпущу grid, данные в WebView отображаются отлично. И когда я нажимаю на сетку, она показывает UIPopover. Мне нужно загрузить 20 сеток, потому что я хочу, чтобы отображалось 20 миниатюр видео на YouTube, чтобы при нажатии на сетку он показывал всплывающее окно с воспроизведением видео в нем.
2. Когда вы делаете сетки видимыми? Можете ли вы включить этот код?
3. спасибо за быстрый ответ. Я думаю, что это имеет смысл. дает вам 1