2010-11-10 26 views
0

我解析一個json對象並將歌曲對象存儲在歌曲中,一個nsmutable數組。當我顯示歌曲的圖像時,即當從數組訪問對象時,其給出該對象中的所有值爲零。在訪問nsmutable數組時給nil

以下代碼在setSongsScrollView方法中,在for循環中從歌曲數組訪問歌曲對象時,它在調試器中顯示爲n且出現錯誤EXEBadacess.But,該數組的計數正確。

任何機構可以幫我請

- (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 
+0

我可以有'Song'的代碼嗎? – tia 2010-11-10 21:39:52

回答

2

馬塞爾基本上得到了正確的答案,但我認爲需要多一點解釋。看看從setSongsScrollView下面幾行:

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

上面一行分配您擁有一首新歌,並分配給它一個參考thesong

thesong = [self.songs objectAtIndex:i]; 

上面一行替換爲一個新的引用引用到你不擁有的陣列中的一首歌。請記住:您現在不擁有歌曲引用的歌曲。現在沒有更多的引用留給你剛分配的對象,但你仍然擁有它。該物體因此泄漏。

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

你正在創建一個新的Song實例(thesong),那麼這很實例分配給一首歌陣列中的大概了。這根本沒有意義,可能是內存錯誤的原因。

如果它們已經在數組中,則不需要創建新歌曲。取而代之:

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

另請參閱使用Objective-C 2.0 for each loop語法。

+0

錯誤來自'[rsong release];'我想。 – tia 2010-11-10 22:32:53

+0

什麼?這甚至不是他遇到問題的方法。 – 2010-11-10 22:38:00

+0

他是對的。代碼在這兩種方法中都犯了同樣的錯誤。 – JeremyP 2010-11-11 10:01:44