views:

406

answers:

1

Hi,

I use datamodel to store 2 objects : Video, Images. Video contain just string attributes and Images have 2 "Binary data" attributes.

At the start the 2 binary data attributes was in the video object. But all videos are loading during initialization of UITableView. For 400 videos binary data represent 20 Mo, so imagine with 4000 videos...

Now with 2 objects the UITableView loading work well. I load binary data when it's necessary in the method : tableView:cellForRowAtIndexPath

But now more I scroll into the list, more the memory grow up :(

look at my method :

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

    static NSString *CellIdentifier = @"videoCell";
    Video *theVideo = (Video *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    VideoCellViewController *cell = (VideoCellViewController *)[myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"VideoCellView" owner:self options:nil];
        cell = editingTableViewCell;
        self.editingTableViewCell = nil;
    }
    cell.video = theVideo;
    return cell;
}

And the method setvideo in VideoCellViewController

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
    }
    NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
    UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
    smallImage.image = uiImage;
    nameLabel.text = video.displayName;
    [uiImage release];
}

Even without set the smallImage, I have memory trouble. If I load the image object, it's never release.

I try a lot of solution to release memory without succes...( didTurnIntoFault, release, CFRelease...) In performance tool, I can see my binary data as CFData.

I use a lot iPhoneCoreDataRecipes and PhotoLocations sample.

I need help to clean my memory ;)

Thanks

Samuel

+1  A: 

Clearly there is something going on with your table cell creation logic. Let's take a look at a typical cellForRow delegate handler first..

static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// do stuff with cell
return cell;

Here we see we are

  • trying to get a reusable cell
  • if that fails (nil) create a new one and pass the reusable id to the ctor
  • then do stuff with the cell (new or existing) and return it

If you do not key the cell for reuse in the table view, you will always get a 'nil' cell returned from the dequeue, hence the need to create new cells every time. This will cause memory to continue to grow as you scroll around, but stay fairly flat when idle.

EDIT:

Assuming your cell is fine, then you need to narrow down if it's the video data or the image data that is leaking. What is smallImage? And are you sure you do not want to do everything only when the video is new?

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
        NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
        UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
        smallImage.image = uiImage;
        nameLabel.text = video.displayName;
        [uiImage release];
    }
}
slf
cell reuse work well in my project (I define cellIdentifier in the nib file). With log I saw just 8 cells creation.I really thinks that is a trouble with binary data release.
Samuel22
added alternate suggestion
slf
Thanks for help ;) smallImage is an UIImageView define in the nib. But even without set smallImage I have memory problem :( Just the valueForKey make trouble. it's never release after... Maybe I have to tell to the NSManagedObjectContext to suppress object in memory for the moment.
Samuel22
are you releasing video in the `dealloc` block?
slf
yes I do. I just cannot release CFData :(
Samuel22
I think I'd have to see more of your code to help you on this one
slf
maybe the solution is to store image into file and not in database. like : http://stackoverflow.com/questions/1015713/storing-binary-data-within-core-data-on-an-iphone
Samuel22
I think that is a better idea, unfortunately a leak is a leak and if you are leaking video now, you'll just end up leaking a path later. You really should find what is leaking and fix it. Time to get out instruments
slf
Yes but no more leak if images are in files...It's maybe a trouble with NSData management. Before when I scroll memory went from 3 to 20 Mo (and more...) and now stands at 3 Mo (even with a list of 4000 movies...)
Samuel22
I would file a radar about that one, make sure you attach your example code http://developer.apple.com/bugreporter/
slf