views:

125

answers:

3

I'm loading a series of images from a server into NSData objects like so:

for (int i = 0; i < 36; i++)
{
 NSURL *url = [NSURL URLWithString:@"http://12.34.56.78/image.jpg"];
 NSData *data = [NSData dataWithContentsOfURL:url];
    // Further processing here
}

The problem is that half of each data object is being kept in memory. This does not show up as a leak in instruments. I know it's the NSData object because I have removed everything having to do with images and really only have the two lines before the comment now. The same behavior occurs. I've tried alloc initing and releasing explicitly with the same result.

The thing that makes this really hard to figure out is that I created a second project to try to recreate this behavior and I can't get it to do so. In the other project, this code acts as expected. So I'm asking, what might cause such behavior? I feel like I'm overlooking something extremely obvious.

A: 

From the two lines you have written, that data object should never leak because you are not retaining it, when you go out of scope that d ata object should autorelease...So cant really tell from the two lines you have posted..

Daniel
Well, like I said, in the version in which I tried to replicate the behavior, it doesn't leak. And, in fact, instruments doesn't consider it a leak, even though my memory usage is steadily increasing. This can only mean that another part of the app is causing the problem, but this is a big app. It's not like I can post the whole thing. I'm kind of just fishing for ideas on what it might be.
eOgas
I would say it somewhere else i supose..
Daniel
A: 

I have encountered something similar where I had an array in my AppDelegate and I was grabbing a reference to a single row then (mistakenly) releasing my handle on the object. The result was that after 3 subsequent calls, the object in the row in question had nil values in all properties but itself was not nil. Took me about a week to figure that one out. To this day I still have no idea why it took 3 calls to release before I noticed a problem. I'm sure you can imagine my frustration when a week later I realized that one line of code was the source of 20 or so wasted hours. ;)

Nathan Taylor
A: 

If what you're seeing is steadily growing memory, use Instruments' Object Allocations probe, and look for what is actually holding the memory. There are many ways to waste memory in ways that are not a "leak." The fact that the size is half the NSData size suggests that you're looking in the wrong place. It is unlikely that you are freeing half an object.

Rob Napier
Actually, the Object Allocations probe is what I used to determine that it's leaking half of the data. It points to the definition of the NSData object as the source of the extra memory. It absolutely HAS to be there too. If I comment out the two lines in my example, I have no memory activity whatsoever, whereas if I leave them as is, the memory slowly grows as the loop executes, and then drops down to the halfway point between where it started, and the peak value. It's quite strange.
eOgas
You know that none of the data objects will be released until your autorelease pool drains, correct? You're going to get 36 copies of this data accumulated. Internally, -dataWithContentsOfURL may be allocating a separate copy of this data, which it may be actively releasing, so what you're seeing as 1/2 the NSData may be just 1 NSData when you temporarily have 2. Replace the autoreleased NSData with an explicit alloc/release and see if the problem doesn't go away.
Rob Napier
I commend you for your creative answer, but we found out what the problem was. Turns out, our app is caching half of every read for some reason (we never explicitly tell it to, but for some reason it's set up to do cache everything it can). Unfortunately, specifying the NSUnchachedRead flag for the options parameter of initWithContentsOfURL:options:error: has no effect. The only solution we've thought of thus far is to create a custom NSData class and simply overload initWithContentsOfURL, disabling any type of caching in the process.
eOgas