After [block copy] and executed block();, should I set block=nil? Or does ARC already manage this for me so I don’t have to do anything?
I’m a bit confused on how ARC manages block references here and I’m not sure setting the block to nil would break anything or not?
I have something like this. Any thoughts?
typedef void (^C3Block)(void); // declare block, no return, no args
// set flag to get _previewImage, then call the block
- (void)takePreviewImageFromBufferWithBlock:(C3Block)block {
_takePreviewImageBlock = [block copy]; // save block ref for calling later
_shouldTakePreviewImageFromBuffer = YES;
}
- (void)gotPreviewImageFromBuffer {
_takePreviewImageBlock(); // calls the block
_takePreviewImageBlock = nil; // <---- should I do this???
}
I think it’s a good idea to set it to
nil, and here is why:Let’s call the class these methods are in
ImageLoader. Suppose I have a classMyViewControllerthat has a strong reference to thisImageLoader(it’s an instance variable, say), and passes it a block that retainsself(i.e. theMyViewController). Why does it retainself? Well, yourImageLoaderpresumably works asynchronously, so, say, I want myMyViewControllerto be around long enough to handle the response.Okay, so we have a retain cycle. The
MyViewControllerretains theImageLoader, which retains the block, which retains theMyViewController. However, if you simplynilthe block variable at the end of the operation inImageLoader, it will break this cycle. Otherwise these objects will never be deallocated. It kind of makes sense forImageLoaderto set the block variable tonilwhen its operation is done because it no longer “needs” it.(You could also argue that the issue in the scenario above could be avoided by arranging the retains differently — that
MyViewControllershould not retainImageLoader. Then, during the asynchronous operation,ImageLoadermust still be retained by something from the ongoing operation.ImageLoaderstill retains the block which retainsMyViewController. When the operation is done, the operation releasingImageLoaderwill release everything, and everyone is happy, without needing to set the block variable tonil.)