Reputation: 12431
I am wondering if I am using blocks as shown in the code below
__block Loader *loader = [[Loader alloc]initWithResourcePath:self.resourcePath];
[loader setCompletionHandler:^(NSArray *anArray){
self.answerArray=anArray;
[self reloadData];
}];
[loader getObjects];
My question is with regards to memory management. The analyzer tells me that there is a potential leak (since I did an alloc/init for my loader). How can I stop the leak here? I tried to release the loader at the end but that causes my app to stop functioning. Any advise is appreciated here
Upvotes: 1
Views: 426
Reputation: 162712
Several issues:
there is no reason for loader
to be declared __block
; you aren't re-assigning in the block and, thus, the __block
is pointless.
the leak is because you alloc/init
the loader, but never release it
do not name methods getSomething
; the get
prefix is reserved for methods that return stuff by reference. Just call it objects
. If it is supposed to trigger the load, then call it load
or performLoad
.
If it is asynchronous, then getObjects
is pointless. If synchronous, then the completion block is pointless.
If loader
is to be used synchronously, release
it at the end of the method. If it is asynchronous
, then the completion block could release it. Note that the use of __block
in this case is still pointless; while referring to loader
in the completion block will create a retain cycle, it will be broken when you explicitly Block_release() the block in your loader
(because you must have done a Block_copy()
when setting the completion handler if it is to be used asynchronously in the first place).
Upvotes: 3
Reputation: 49
I'm going to make some assumptions: 1) The completion handler (block) is used by method getObjects. 2) getObjects is asynchronous (it returns to the caller right away though it continues to process).
With these assumptions you can't send release after sending getObjects because getObjects is still using the completion handler.
Try sending a release or autorelease at the end of the completion handler. That should free loader provided reloadData is not also asynchronous.
Upvotes: 1
Reputation: 69027
If you plan to use loader
outside of the function calling your block, it is highly possible that you need to store it in a ivar of your controller (I guess, it is a controller, but I don't know what kind of class owns the code you shows). Once you do that, you can release it in your dealloc
.
The reasoning is that loader
should live across several methods and runloop cycles, so a local variable will not do.
Otherwise, just release it at the end of the block, once you have done with it.
If this does not seem right to you, then possibly more code is needed.
Upvotes: 1