1

次のコードを使用してサーバーから画像をロードするために次のコードを使用しています。スクロールすると、UITableViewアプリケーションがクラッシュします。

AsynchrohousImageViewクラスの.mファイル

- (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];
}

画像をロードするViewControllerクラス内

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



static NSString *reuseIdentifier =@"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;
}

どうすればこれを解決できますか?ヒープショット分析のスクリーンショットを添付しました。ここでは、非オブジェクトが大量のメモリを消費します。これは何ですか。ヒープショット分析

4

2 に答える 2

5

これはエラーです:

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

セルを再利用していないようですが、テーブルのすべての行に新しいセルを作成しています!!! このようにして、100行または1000行を表示する必要がある場合は、100行または1000行のオブジェクトセルを作成/割り当てます。

これは、UITableViewの正しい使用法ではありません。UITableViewの「魔法」は、セルを再利用し、必要な少数のセルだけを作成して割り当てることです。

たとえば、テーブルに480ピクセルの垂直方向のスペースがあり、セルの高さが100ピクセルの場合、時間に必要なセルは5つだけで、1000個のセルを作成する必要はなく、一度に5つのセルしか表示できません...

したがって、魔法は、セルを上にスクロールして画面から消えたときに、すでに割り当てられているセルを再利用し、その内容(画像とテキスト)をリセットして、ユーザーが見下ろす新しい呼び出しに使用することです...

于 2012-04-06T11:10:34.627 に答える
2

セルの再利用は問題ではありませんが、セルのリークは次のとおりです。

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

あなたはこれを忘れたautoreleaseので、あなたは非常に速く細胞を漏らしています。自動リリースすることを覚えていましたcell1

于 2012-04-06T12:51:24.130 に答える