5

I have some operations that are inside blocks. This operations, only update an UIImage like this:

^(UIImage *image) {
            self.myImage = image;
        }];

My image is calculated by accessing the internet with a NSURLConnection. When I receive the image from the internet, I call that block that is inside a NSMutableArray. So far so good. My issue is that when I have multiple images that have the same URL, instead of making multiple calls, I just add a new block to the NSMutableArray inside the class that handles the connection. This way, I make one single call, and update multiple images that share the URL. Everything works ok, the problem is that I am leaking blocks. I add the block like this to the NSMutableArray:

 if( (self = [super init]) ) 
    {
        self.connectionURL=url;
        self.arrayOfBlocks=[NSMutableArray array];
        [arrayOfBlocks addObject:completion];
    }
    return self;

This is when the connection class is initialized. This is when I need to add a new block to the NSMutableArray (I only add it, and that's it):

[arrayOfBlocks addObject:completion];

This is when I finally receive the call back, and start executing the blocks:

 for (MyBlock blockToExecute in arrayOfBlocks)
    {
        blockToExecute([UIImage imageWithData:data]);
    }

The problem is that this is leaking somehow. I am not able to counteract using releases or auto-releases because I am on ARC environment. So what could be a solution?


enter image description here

Kazuki Sakamoto
  • 13,929
  • 2
  • 34
  • 96
Rui Peres
  • 25,741
  • 9
  • 87
  • 137
  • 1
    The leaks in your screenshot are not coming from the code you posted. Those are C-style strings created by the `strdup()` function deep in the frameworks. I don't think you should worry about them. I think they are either false positives or due to bugs in the frameworks. – Ken Thomases May 09 '12 at 09:51
  • Actually Ken, I have been monitoring the app, and the leaks are still coming, although the blocks are not being used anymore (since you already got the images, you don't need to use them again) – Rui Peres May 09 '12 at 09:55

2 Answers2

6

This is a well-known leak in Apple's frameworks. It isn't caused by your use of blocks.

Here's a previous question about it and a bug report.

Community
  • 1
  • 1
Kurt Revis
  • 27,695
  • 5
  • 68
  • 74
0

The block retains 'self', and I'm guessing that 'self' retains the blocks (via the 'arrayOfBlocks' property). If that property is retained, you have a circular reference and a leak. I don't think ARC handles circular references, so you should probably empty the block array after you're done with it (or set the property to nil), and make sure nothing else references the blocks.

Vladimir Gritsenko
  • 1,669
  • 11
  • 25
  • So what you are suggestion is a simple: self.arrayOfBlocks=nil? Because I have tried and still leaks. – Rui Peres May 09 '12 at 11:23
  • Is anyone else holding references to that array, and is anyone else holding references to those blocks? – Vladimir Gritsenko May 09 '12 at 11:28
  • No that array no. To the blocks I don't think so either. The only thing I am seeing is: self.myImage = image; – Rui Peres May 09 '12 at 11:47
  • In your code, the block is not created directly but comes from the 'completion' parameter. Any chance it's retained in outside code? If not, then I'm out of ideas, though I still suspect some sort of circular reference shenanigans. – Vladimir Gritsenko May 09 '12 at 11:56