2012-04-06 3 views
1

다음 코드를 사용하여 서버에서 이미지를로드하는 데 다음 코드를 사용하고 있습니다. UITableView 응용 프로그램이 충돌 할 때 스크롤합니다.응용 프로그램이 메모리 부족 경고를 표시하고 이미지를로드하는 동안 충돌이 발생합니까?

AsynchrohousImageView 클래스하는 .m 파일 이미지가

- (UITableViewCell *)tableView:(UITableView *)tV cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 



static NSString *reuseIdentifier [email protected]"CellIdentifier"; 
    ListCell *cell = (ListCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
    if (cell==nil) { 
     cell = [[ListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 
     NSMutableDictionary *dicResult = [arrResults objectAtIndex:indexPath.row]; 

    NSURL *url=[NSURL URLWithString:[dicResult objectForKey:@"Image"]]; 
    AsynchronousImageView *asyncImageView = [[AsynchronousImageView alloc] initWithFrame:CGRectMake(5, 10,80,80)]; 
    [asyncImageView loadImageFromURL:url 
        defaultImageName:@"DefaultImage.png" 
        showDefaultImage:NO 
       showActivityIndicator:YES 
       activityIndicatorRect:CGRectMake(5, 10,30,30) 
       activityIndicatorStyle:UIActivityIndicatorViewStyleGray]; // load our image with URL asynchronously 

    [cell.contentView addSubview:asyncImageView]; 
    // cell.imgLocationView.image = [UIImage imageNamed:[dicResult valueForKey:@"Image"]]; 
    [asyncImageView release]; 

} 

if([arrResults count]==1) 

{ 
    UITableViewCell *cell1=[tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
    if(cell1==nil) 
     cell1=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease]; 
    NSMutableDictionary *dicResult = [arrResults objectAtIndex:0]; 
    cell1.textLabel.text=[dicResult valueForKey:@"NoResults"]; 
    return cell1; 
} 
else 
{ 
NSMutableDictionary *dicResult = [arrResults objectAtIndex:indexPath.row]; 
NSString *title = [NSString stringWithFormat:@"%@ Bedrooms-%@", [dicResult valueForKey:KEY_NUMBER_OF_BEDROOMS],[dicResult valueForKey:KEY_PROPERTY_TYPE]]; 
NSString *strAddress = [dicResult valueForKey:KEY_DISPLAY_NAME]; 
NSString *address = [strAddress stringByReplacingOccurrencesOfString:@", " withString:@"\n"]; 
NSString *price = [dicResult valueForKey:KEY_PRICE]; 
NSString *distance = [dicResult valueForKey:KEY_DISTANCE]; 
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

     cell.lblTitle.text = title; 
cell.lblAddress.text = address; 
if ([price length]>0) { 
    cell.lblPrice.text = [NSString stringWithFormat:@"£%@",price]; 
}else{ 
    cell.lblPrice.text = @""; 
} 
if ([distance length]>0) { 
    cell.lblmiles.text = [NSString stringWithFormat:@"%.2f miles",[distance floatValue]]; 
}else{ 
    cell.lblmiles.text = @""; 
} 


} 
return cell; 
} 

어떻게이 문제를 해결할 수있는로드의 ViewController 클래스에서

- (void)dealloc { 
[connection cancel]; //in case the URL is still downloading 
[connection release]; 
[data release]; 
[_imageView release]; 
[_activityIndicator release]; 
[super dealloc]; 
} 

- (void)loadImageFromURL:(NSURL*)url 
    defaultImageName:(NSString *)defaultImageName 
    showDefaultImage:(BOOL)defaultImageIsShown 
    showActivityIndicator:(BOOL)activityIndicatorIsShown 
    activityIndicatorRect:(CGRect)activityIndicatorRect 
    activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle { 

if (connection!=nil) { [connection release]; } if (data!=nil) { [data release]; } 

if ([[self subviews] count]>0) { 
    [[[self subviews] objectAtIndex:0] removeFromSuperview]; // } 

if (defaultImageIsShown) { 
     self.imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:defaultImageName]] autorelease]; 
} else { 
    self.imageView = [[[UIImageView alloc] init] autorelease]; 
} 


[self addSubview:_imageView]; 
_imageView.frame = self.bounds; 
[_imageView setNeedsLayout]; 
[self setNeedsLayout]; 

if (activityIndicatorIsShown) { 

    self.activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:activityIndicatorStyle] autorelease]; 
    [self addSubview:_activityIndicator]; 
    _activityIndicator.frame = activityIndicatorRect; 
    _activityIndicator.center = CGPointMake(_imageView.frame.size.width/2, _imageView.frame.size.height/2); 
    [_activityIndicator setHidesWhenStopped:YES]; 
    [_activityIndicator startAnimating]; 
} 


NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
} 


- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData { 
if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; } 
[data appendData:incrementalData]; 
    } 

    - (void)connectionDidFinishLoading:(NSURLConnection*)theConnection { 
    [connection release]; 
    connection=nil; 

    _imageView.image = [UIImage imageWithData:data]; 

if (_activityIndicator) { 
    [_activityIndicator stopAnimating]; 
} 

[data release];  data=nil; 
} 


- (UIImage*) image { 
UIImageView* iv = [[self subviews] objectAtIndex:0]; 
return [iv image]; 
} 

? 나는 힙샷 분석 스크린 샷을 붙였다. 여기에 Object가 없으면 메모리가 많이 소모된다. Heap Shot Analysis

답변

5

이 오류입니다 : 당신이 세포를 다시 사용하지만 테이블의 모든 행에 대해 새로운 세포를 생성하지 않는 것 같다

NSString *reuseIdentifier = [NSString stringWithFormat:@"%d",indexPath.row]; 

! 이렇게하면 100 또는 1000 개의 행을 볼 때 100 또는 1000 개의 개체 셀을 생성/할당 할 수 있습니다.

그것은 UITableView의 올바른 사용법이 아닙니다. UITableView의 "마법"은 세포를 재사용한다는 것입니다. 단지 세포의 부수를 생성하고 할당하기 만하면됩니다 ...

예 : 귀하의 테이블에 대한 480 픽셀의 수직 공간을 가지고 귀하의 세포가 100 픽셀 높이라고 가정하면 시간당 5 개의 셀이 필요하며 1000 개의 셀을 만들 필요가 없으며 시간당 5 개의 셀을 볼 수 있습니다 ...

그래서 마법은 이미 스크롤 한 셀을 위로 스크롤하면 화면 밖으로 나가고, 내용 (이미지 및 텍스트)을 재설정하고 사용자가 보게 될 새 호출에 사용하도록 마법을 사용합니다. ..

+0

정적 NSString * CellIdentifier = @ "CellIdentifier"로 변경 한 경우에도 응용 프로그램에서 메모리가 손상 될 수 있습니다. – Bhoomi

+1

셀을 다시 사용하지 않아도 테이블보기에 셀 수가 제한되지 않습니다. 이는 일반적으로 느린 속도로 요구에 따라 재생성 할 수 있음을 의미합니다. Bhoomi가 지적했듯이, 이것은 메모리 문제를 해결해서는 안됩니다. –

+0

rob은 맞습니다. 물론 그에게 +1을주었습니다 ... 저에게 잘못 생각한 코드의 첫 번째 줄에 막 멈췄습니다 ... 그리고 그것은 당신이 올바른 방식으로 테이블을 사용하지 않는다는 것을 보여주었습니다. . 아마도 사과 샘플을보고 어떻게 작동하는지 이해해야합니다. – meronix

2

세포 재사용, 문제가없는 세포를 유출하는 동안 :

cell = [[ListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 

당신은 autorelease이 깜빡, 당신이 르있어 그래서 세포를 매우 빠르게 공격한다. 자동 회수를 기억하셨습니까 cell1.

관련 문제