访问 nsmutable 数组时给出 nil
我正在解析一个 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
i am parsing a json object and storing the song objects in songs, a nsmutable array.
while am displaying the image of the song i.e. while accessing the object from the array its giving all values nil in that object.
in the following code in setSongsScrollView method, in for loop while accessing the song object from songs array its showing nill in the debugger and crashing with error EXEBadacess.But the count of that array is giving correct.
can any body help me out please
- (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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
马塞尔基本上得到了正确的答案,但我认为还需要更多解释。查看 setSongsScrollView 中的以下几行:
上面的行分配您拥有的一首新歌曲,并将对其的引用分配给 thesong
上面的行将该引用替换为对您不拥有的数组中的一首歌曲的新引用。请记住:您现在不拥有该歌曲引用的歌曲。现在,您刚刚分配的对象不再有任何引用,但您仍然拥有它。因此该对象已泄漏。
使用
stringByAppendingPathComponent:
构建文件路径,而不是stringWithFormat:
。上述序列中的最后一行释放了 thesong 引用的对象。如上所述,您不拥有该对象。你不能释放它,但你还是释放了它。这意味着,在某个时刻,可能是现在,也可能是稍后,对象将被释放,而某些东西(可能是数组)仍然认为它具有有效的引用。这就是导致崩溃的原因。
上述方法包含完全相同的错误。
Marcel has basically got the right answer but I think a little more explanation is needed. Look at the following lines from setSongsScrollView:
The above line allocates a new Song that you own and assigns a reference to it to thesong
The above line replaces that reference with a new reference to a song from the array that you don't own. Remember that: you do not own the song referenced by thesong now. There are now no more references left to the object you just allocated, but you still own it. The object has therefore leaked.
Use
stringByAppendingPathComponent:
to build file paths, notstringWithFormat:
.The last line in the above sequence releases the object referenced by thesong. As noted above, you do not own that object. You must not release it, but you have anyway. This means that, at some point, may be now, maybe later, the object will be deallocated while something (probably the array) still thinks it has a valid reference. That's what causes the crash.
The above method contains exactly the same error.
您正在创建一个新的
Song
实例(歌曲),然后将此实例分配给可能已在数组中的歌曲。这根本没有意义,并且可能是造成内存错误的原因。如果新歌曲已经在数组中,则不需要创建新歌曲。相反:
还要考虑使用 Objective-C 2.0 for-each 循环语法。
You're creating a new
Song
instance (thesong), then assign this very instance to a song presumably already in the array. That makes no sense at all and is probably responsible for the memory error.You shouldn't need to be creating new Songs if they are already in the array. Instead:
Also look into using the Objective-C 2.0 for-each loop syntax.