Blocks inside NSMutableArray leaking (ARC)

2019-02-13 23:07发布

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

2条回答
可以哭但决不认输i
2楼-- · 2019-02-13 23:37

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.

查看更多
乱世女痞
3楼-- · 2019-02-13 23:53

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.

查看更多
登录 后发表回答