дает ноль при доступе к массиву nsmutable - PullRequest
0 голосов
/ 10 ноября 2010

Я анализирую объект json и сохраняю объекты песни в песнях, массив nsmutable.в то время как я показываю изображение песни, т.е. когда он обращается к объекту из массива, он дает все значения nil в этом объекте.

в следующем коде в методе setSongsScrollView, в цикле for при доступе к объекту песни из массива песенон показывает ноль в отладчике и вылетает с ошибкой EXEBadacess. Но счет этого массива дает правильное значение.

Может ли любое тело помочь мне, пожалуйста

- (void)viewWillAppear:(BOOL)animated{ 
 [super viewDidLoad];
 [self parsingTheStation];
 [self load_images];
 [self setSongsScrollView];
}

/*
 // Implement loadView to create a view hierarchy programmatically, without using a nib.
 - (void)loadView {
 }
 */


- (void)parsingTheStation{
 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http:...."]];
 NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
 NSString *jsonString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
 NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
 NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];

 songs =[[NSMutableArray alloc]init];
 NSArray *songObjects = [dictionary objectForKey:@"songs"];
 for(NSDictionary *s in songObjects){
  aSong = [[Song alloc] init];
  aSong.artist = [s objectForKey:@"by"];
  aSong.genre = [s objectForKey:@"genre"];
  aSong.cover = [s objectForKey:@"cover"];
  aSong.song_id = [s objectForKey:@"id"];
  aSong.rank = [s objectForKey:@"rank"];
  aSong.title = [s objectForKey:@"title"];
  aSong.link = [s objectForKey:@"link"];
  [songs addObject:aSong];
  [aSong release];  
 }

 NSLog(@"total number of songs is : %d",[songs count]);

}

-(void)setSongsScrollView {
 songsContainer = [[UIScrollView alloc]init];
 int songsCount = [self.songs count];
 //totla no. of songs we get +4
 int tSongs = songsCount+4;
 int n = sqrt(tSongs);
 int p = n,q = n;
 int remSongs = tSongs-(n*n);
 if(remSongs >= n){
  q = q+(remSongs/n);
  if((remSongs%n)>0)
   q++;
 }else q++;
 for(int i=0;q>p;i++){
  q--;
  p++;
 }

 NSLog(@"total songs..%d",tSongs);
 NSLog(@"total rows..%d",q);
 NSLog(@"total columns..%d",p); 

 songsContainer.contentSize = CGSizeMake(120*q, 120*p);
 int x =0, y=240, col=1;
 for(int i=0;i<songsCount;i++){
  CGRect imgFrame = CGRectMake(x, y, 118, 118);
  NSLog(@"songs conunt ...%d",[songs count]);
  Song *thesong = [[Song alloc]init];
  thesong = [self.songs objectAtIndex:i];
  NSString *filename = [NSString stringWithFormat:@"%@/%@", [LazyImageView dataPath], [thesong.cover lastPathComponent]];
  UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
  tempImg.tag = i;
  tempImg.frame = imgFrame;
  [songsContainer addSubview:tempImg];
  [tempImg release];
  [thesong release];

  y += 120;
  if(y>=(120*p)){
   NSLog(@"total y..%d",y);
   col++;
   x += 120;
   if(col>=3)
    y=0;
   else 
    y=240;
  }  
 }
 NSLog(@"total y..%d",y);
 NSLog(@"content size..%d,%d",120*q,120*p);
}

-(void)load_images{
 for(int i=0;i<[songs count];i++){
  Song *rsong = [[Song alloc]init];
  rsong = [self.songs objectAtIndex:i];
  lazyBigImg = [[LazyImageView alloc] init];
  NSURL* url = [NSURL URLWithString:rsong.cover];
  [lazyBigImg loadImageFromURL:url];
  [lazyBigImg release];
  [rsong release];
 }
}

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
 [songs release];
 [lazyBigImg release];
 [onAirBtn release];
 [chartsBtn release];
 [dealsBtn release];
 [searchBtn release];
 [stNameLbl release];
 [aSong release];
 [songsContainer release];
    [super dealloc];
}


@end

Ответы [ 2 ]

2 голосов
/ 11 ноября 2010

Марсель в основном получил правильный ответ, но я думаю, что нужно немного больше объяснений.Посмотрите на следующие строки из setSongsScrollView:

Song *thesong = [[Song alloc]init];

Приведенная выше строка выделяет новую песню, которой вы владеете, и присваивает ссылку на эту песню

thesong = [self.songs objectAtIndex:i];

Приведенная выше строка заменяет эту ссылкус новой ссылкой на песню из массива, который вам не принадлежит.Помните, что: вам не принадлежит песня, на которую ссылается thesong сейчас.Теперь больше нет ссылок на объект, который вы только что разместили, но вы все еще являетесь его владельцем.Поэтому объект просочился.

NSString *filename = [NSString stringWithFormat:@"%@/%@", [LazyImageView dataPath], [thesong.cover lastPathComponent]];

Используйте stringByAppendingPathComponent: для построения путей к файлам, а не stringWithFormat:.

UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
tempImg.tag = i;
tempImg.frame = imgFrame;
[songsContainer addSubview:tempImg];
[tempImg release];
[thesong release];

Последняя строка в приведенной выше последовательности освобождает объект, на который ссылаетсяпесня.Как отмечалось выше, вы не являетесь владельцем этого объекта.Вы не должны выпускать это, но у вас все равно есть.Это означает, что в какой-то момент может быть сейчас, а может и позже, объект будет освобожден, в то время как что-то (возможно, массив) все еще думает, что оно имеет действительную ссылку.Вот что вызывает сбой.

-(void)load_images{
 for(int i=0;i<[songs count];i++){
  Song *rsong = [[Song alloc]init];
  rsong = [self.songs objectAtIndex:i];
  lazyBigImg = [[LazyImageView alloc] init];
  NSURL* url = [NSURL URLWithString:rsong.cover];
  [lazyBigImg loadImageFromURL:url];
  [lazyBigImg release];
  [rsong release];
 }
}

Вышеуказанный метод содержит точно такую ​​же ошибку.

1 голос
/ 11 ноября 2010

Вы создаете новый экземпляр Song (thesong), а затем назначаете этот самый экземпляр песне, предположительно, уже в массиве.Это не имеет никакого смысла и, вероятно, ответственно за ошибку памяти.

Вам не нужно создавать новые песни, если они уже есть в массиве.Вместо этого:

Song *thesong = [self.songs objectAtIndex:i];

Также обратите внимание на использование синтаксиса цикла Objective-C 2.0 для каждого.

...