tags:

views:

96

answers:

2

Hi, using sdk 4.1. I'm getting growing memory footprint followed by crash (observed in Instruments) when loading a thumbnail image into imageview in table view cell. In addition scrolling is very jerky even with just 7-8 cells

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

     static NSString *FavouritesCellIdentifier = @"cellIdentifier";


 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 if (cell == nil) 
 {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                    reuseIdentifier:cellIdentifier] autorelease];

    UIImageView* imgView =  [[UIImageView alloc] initWithFrame:CGRectMake(10,
                                                                     16, 64, 64)];
    imgView.tag = kImageLabelTag;
    [cell.contentView addSubview:imgView];
    [imgView release];

   }

   UIImageView* imgView = (UIImageView*)[cell viewWithTag:kImageLabelTag];

    NSData *contactImageData = (NSData*)ABPersonCopyImageDataWithFormat(personRef,  
                                                    kABPersonImageFormatThumbnail);
    UIImage *img = [[UIImage alloc] initWithData:contactImageData];
   [imgView setImage:img]; 
   [contactImageData release];
  [img release];

    return cell;
  }

In viewdidunload i am setting self.tableview=nil , is there anyway to release the images held by the cell as memory footprint keeps growing even when navigating to totally different viewcontroller. Memory shoots up only when selecting the viewcontroller that holds this tableview.

A: 

I thing that the fact that you cast your CFDataRef to a NSData is the problem. I guess the release method doesn't do anything since the pointer is actually a pointer to a CFDataRef object that is supposed to be released using CFRelease function.

Try :

UIImageView* imgView = (UIImageView*)[cell viewWithTag:kImageLabelTag];

CFDataRef contactImageData = ABPersonCopyImageDataWithFormat(personRef,  
                                                    kABPersonImageFormatThumbnail);
UIImage *img = [[UIImage alloc] initWithData:(NSData*)contactImageData];
[imgView setImage:img]; 
CFRelease(contactImageData);
[img release];
VdesmedT
Hi, i believe they are interchangeable, anyway it made no difference
tech74
+1  A: 

The reason for crash is that you're releasing NSData object which you shouldn't.

And the scrolling of the table should be slow always because with each scroll, it will call cellForRowAtIndexPath method & with it will create a new image.

So try the below code & let me know whether it works or not

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

static NSString *FavouritesCellIdentifier = @"cellIdentifier";


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:cellIdentifier] autorelease];

    UIImageView* imgView =  [[UIImageView alloc] initWithFrame:CGRectMake(10, 16, 64, 64)];
    imgView.tag = kImageLabelTag;
    [cell.contentView addSubview:imgView];
    [imgView release];

    NSData *contactImageData = (NSData*)ABPersonCopyImageDataWithFormat(personRef, kABPersonImageFormatThumbnail);
    UIImage *img = [[UIImage alloc] initWithData:contactImageData];
    [imgView setImage:img]; 
    [img release];

}

return cell;

}

Sagar
Good eye catch. I think this is his problem
vodkhang
According to http://developer.apple.com/library/mac/#DOCUMENTATION/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html, since ABPersonCopyImageDataWithFormat has copy in the name, you own the returned reference, and therefore you should release it, am I wrong? Instruments doesn't detect leaks directly when you omit a CFRelease on the CFDataRef, but the memory usage keeps growing.
Michael Baltaks