Must I copy a block here? - objective-c

I understand that you must copy blocks in order for them to stick around after a stack frame exits. But, how does that apply to stack-allocated blocks used within a nested block as in the following code example:
- doSomethingFunkyThenCall:(void(^)(int someValue))callback
{
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
// ... do some work here, potentially nesting into further blocks ...
callback(result);
}];
}
Obviously, the doSomethingFunkyThenCall: stack frame will terminate before the callback is executed, so it will have to be copied. But will this happen automatically in the call to addOperationWithBlock: or do I have to do it manually?

Most likely, it will happen automatically. Cocoa's design principles imply in general that you're not responsible for objects (their memory management, passing blocks [which are, in fact, implemented as proper Objective-C objects], etc.) you haven't created. So you can just pass down the block you received as a parameter, and the runtime will manage it as per its needs.

Yes, you should do a callback = [[callback copy] autorelease]; at the top of this method.
Objects used in blocks are retained automatically, but sending a stack-block retain actually does nothing (because the semantics of retain require it to return the receiver), so will be gone once we leave the frame it was created in.
Sources:
http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html
http://thirdcog.eu/pwcblocks/#objcblocks
EDIT: It turns out I'm wrong. #bbum points out below that Block_copy will copy recursively, and since addOperationWithBlock: copies it's block, the callback is also copied.

Related

Purposely Create Retain Cycle (Objective C without GC)

Is there ever a case where purposely creating a retain cycle to prevent deallocation, then cleaning it up later, is the best solution to a problem?
If so, are there examples of this in the Cocoa Touch or NextStep frameworks?
I intend this question to be specific to Objective C with ARC since Objective C with GC or other languages with GC may behave differently.
Sure. It's actually not all that uncommon, though you may not realize it.
For example, let's assume that my controller is making a network request, and I really need to make sure I handle the response, even if the user has navigated away from that controller.
I might do something like this:
- (void)doNetworkThing {
__block MyController *blockSelf = self;
NSURLRequest *request = // some request
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error) {
// Handle the response here
[blockSelf doThingWithResponse:response];
}];
}
This introduces a trivial retain cycle where self has caused itself to be retained by assigning itself to the strong pointer blockSelf. Until blockSelf goes out of scope, self will not be deallocated.
Note that often, you would use a weak pointer in this situation. But if you really need the controller to be around to handle it, using a strong pointer works too. As soon as the handler block is deallocated, its reference to blockSelf will go away. Since the the stack reference to blockSelf is also gone self will then be deallocated if nobody else is holding on to it.
So basically, blockSelf caused a temporary retain cycle, which was useful in ensuring that deallocation could not happen until the request finished. Because ARC automatically cleans up the retain counts when the __block variable goes out of scope, it doesn't look much like a retain cycle. But nevertheless, that's what it is.
Sure, there are several. Most notably NSURLConnection generates a retain loop with its delegate to ensure that the delegate cannot go away before the connection completes. Somewhat less ideally, NSTimer generates a retain loop with its target. This unfortunately causes problems for repeating timers (see RNTimer for one of many attempts to work around this issue).
Generally speaking, if a delegating object has a very short lifespan compared to its delegate, it is natural for it to retain its delegate in order to create a beneficial retain loop.
It is much less common, but still done, for certain kinds of objects to "self retain." For example, if you had an object that you wanted to create and have some operation perform, and then destroy itself, then self retain can solve that problem. Typically it is better to avoid that and let the caller retain the object, but it still has its uses (I've used it for logging and other non-critical operations that I want to fire-and-forget).
That said, it is not uncommon in my code to intentionally create short-lived retain loops with blocks to ensure that the calling object cannot vanish before the block finishes.

When do I release this block?

I was looking at some code in this thread How do you trigger a block after a delay, like -performSelector:withObject:afterDelay:?. I was wondering, if the block does something asynchronously, when should the block be released?
Let's say I have code that looks like this:
- (void)testMethod:(id)parameter
{
dispatch_block_t block = ^{
SomeAsyncTask *t = [SomeAsyncTask withCompletionBlock:^{
[parameter doAction];
}];
};
[self performSelector:#selector(executeBlock:)
onThread:backgroundThread
withObject:block
waitUntilDone:NO];
dispatch_release(block); //I can release the block here because performSelector retains the block
}
- (void)executeBlock:(id)block
{
block();
}
Is the key then, that the completion block in SomeASyncTask will retain the parameter so it's safe to release the block?
Ken Thomases's answer is correct. I want to give a more detailed response to your comments.
First, it is not clear whether you meant performSelector:withObject: or performSelector:withObject:afterDelay:, since performSelector:withObject: is a direct synchronous call, so [self performSelector:#selector(runBlock:) withObject:block_]; is identical to [self runBlock:block_]. I'll assume it's performSelector:withObject:afterDelay:, since performSelector:withObject: is less interesting.
Look at it step by step. performSelector:withObject:afterDelay: retains its argument, so you can release it after giving the block to it. And performSelector:... retains it through the performance of its selector. So during the runBlock, the block is valid because it is still retained by performSelector:.... During the execution of the block, it is still valid (since it is still inside the execution of runBlock). doSomethingAsynchronouslyWithCompletionBlock must retain its argument if it is asynchronous. And so on.
But you don't need to look at it that way. Once you think through it, you will realize that the memory management rules are made so that you don't need to worry about what other code does, only what you need locally.
The memory management rules boil down to the following conditions: Every function / method expects its arguments to be valid when it is called (which usually means through the duration of the function call, since the calling function does not run during this time, so how can it become invalid, unless this function does something which indirectly removes it (like removing from a dictionary)?); and does not have any expectations about how long it will remain valid after the function call. That's it. Everything follows from this.
For example, in your doWork, you only care about how long you need to use the block. Since you don't need it after performSelector:..., you can safely release it. It doesn't matter that performSelector:... might do something with it asynchronously; you may not even know that it is asynchronous (e.g. you could be choosing an unknown method to call dynamically). The point is, what it does doesn't matter. Why? Because the performSelector:... does not assume the argument to be valid any longer than when you called it. So if it needs to keep it longer (and it does), it must retain it (but you don't need to know this). And it will retain it for as long as it needs it.
Similarly, runBlock can assume that the argument it was given is valid for the duration of its call. Since it does not need to keep it around for longer (all it does is call the block), it does not need to retain it. The block does not change this. Why? Again, because the block does not assume its arguments (including the block itself) is valid after its call, so runBlock doesn't need to guarantee it. If the block calls doSomethingAsynchronouslyWithCompletionBlock, that's fine. doSomethingAsynchronouslyWithCompletionBlock does not assume anything is valid beyond its call, so if it is truly asynchronous, it must retain it somewhere. etc.
You can release it immediately after invoking -performSelector:withObject:afterDelay:. (I assume you meant to use the after-delay variant.) As usual, you are responsible for your memory management and other code is responsible for its memory management. Which is another way of saying that -performSelector:withObject:afterDelay: has to retain the receiver and the object that's passed in until after the selector has been performed.
Edited to add: By the way, why wouldn't you use dispatch_after() as illustrated in the answer to the question to which you linked?
I might just try passing an array with the arguments.

Passing blocks in Objective-C

When writing a method that accepts a block as an argument, do I need to do anything special such as copying the block to the heap before executing it? For example, if I had the following method:
- (void)testWithBlock:(void (^)(NSString *))block {
NSString *testString = #"Test";
block(testString);
}
Should I do anything with block before calling it, or when entering the method? Or is the above the correct way of using the passed-in block? Also, is the following way of calling the method correct, or should I do something with the block before passing it?
[object testWithBlock:^(NSString *test){
NSLog(#"[%#]", test);
}];
Where do I need to copy the block? And how would this have been different if I wasn't using ARC?
When you receive a block as a method parameter, that block could be the original that had been created on the stack or it could be copy (a block on the heap). As far as I'm aware, there's no way tell. So the general rule of thumb is if you're going to execute the block within the method that's receiving it, you don't need to copy it. If you intend to pass that block to another method (which may or may not execute it immediately) then you also don't need to copy it (the receiving method should copy it if it intends to keep it around). However, if you intend to store the block in any way for some place for later execution, you need to copy it. The primary example many people use is some sort of completion block held as an instance variable:
typedef void (^IDBlock) (id);
#implementation MyClass{
IDBlock _completionBlock;
}
However, you also need to copy it if you're going to add it to any kind of collection class, like an NSArray or NSDictionary. Otherwise, you'll get errors (most likely EXC_BAD_ACCESS) or possibly data corruption when you try to execute the block later.
When you execute a block, it's important to test first if the block is nil. Objective-c will allow you to pass nil to a block method parameter. If that block is nil, you'll get EXC_BAD_ACCESS when you try to execute it. Luckily this is easy to do. In your example, you'd write:
- (void)testWithBlock:(void (^)(NSString *))block {
NSString *testString = #"Test";
if (block) block(testString);
}
There are performance considerations in copying blocks. Compared to creating a block on the stack, copying a block to the heap is not trivial. It's not a major deal in general, but if you're using a block iteratively or using a bunch of blocks iteratively and copying them on each execution, it'll create a performance hit. So if your method - (void)testWithBlock:(void (^)(NSString *))block; were in some kind of loop, copying that block might hurt your performance if you don't need to copy it.
Another place you need to copy a block is if you intend on calling that block in itself (block recursion). This isn't all that common, but you must copy the block if you intend to do this. See my question/answer on SO here: Recursive Blocks In Objective-C.
Finally, if you're going to store a block you need to be really careful about creating retain cycles. Blocks will retain any object passed into it, and if that object is an instance variable, it will retain the instance variable's class (self). I personally love blocks and use them all the time. But there's a reason Apple doesn't use/store blocks for their UIKit classes and instead stick with either a target/action or delegate pattern. If you (the class creating the block) are retaining the class that is receiving/copying/storing the block, and in that block you reference either yourself or ANY class instance variable, you've created a retain cycle (classA -> classB -> block -> classA). This is remarkably easy to do, and it's something I've done too many times. Moreover, "Leaks" in Instruments doesn't catch it. The method to get around this is easy: simply create a temporary __weak variable (for ARC) or __block variable (non-ARC) and the block won't retain that variable. So,for example, the following would be a retain cycle if the 'object' copies/stores the block:
[object testWithBlock:^(NSString *test){
_iVar = test;
NSLog(#"[%#]", test);
}];
However, to fix this (using ARC):
__weak IVarClass *iVar = _iVar;
[object testWithBlock:^(NSString *test){
iVar = test;
NSLog(#"[%#]", test);
}];
You can also do something like this:
__weak ClassOfSelf _self = self;
[object testWithBlock:^(NSString *test){
_self->_iVar = test;
NSLog(#"[%#]", test);
}];
Note that many people don't like the above because they consider it fragile, but it is a valid way of accessing variables.
Update - The current compiler now warns if you try to directly access a variable using '->'. For this reason (as well as reasons of safety) it's best to create a property for the variables you want to access. So instead of _self->_iVar = test; you would use: _self.iVar = test;.
UPDATE (more info)
Generally, it's best to consider the method that receives the block as responsible for determining whether the block needs to be copied rather than the caller. This is because the receiving method can be the only one that knows just how long the block needs to be kept alive or if it needs to be copied. You (as the programmer) will obviously know this information when you write the call, but if you mentally consider the caller and receiver at separate objects, the caller gives the receiver the block and is done with it. Therefore, it shouldn't need to know what is done with the block after it's gone. On the flip side, it's quite possible that the caller may have already copied the block (maybe it stored the block and is now handing it off to another method) but the receiver (who also intends on storing the block) should still copy the block (even though the block as already been copied). The receiver can't know that the block has already been copied, and some blocks it receives may be copied while others may not be. Therefore the receiver should always copy a block it intends on keeping around? Make sense? This essentially is good Object Oriented Design Practices. Basically, whoever has the information is responsible for handling it.
Blocks are used extensively in Apple's GCD (Grand Central Dispatch) to easily enable multi-threading. In general, you don't need to copy a block when you dispatch it on GCD. Oddly, this is slightly counter-intuitive (if you think about it) because if you dispatch a block asynchronously, often the method the block was created in will return before the block has executed, which generally would mean the block would expire since it is a stack object. I don't think that GCD copies the block to the stack (I read that somewhere but have been unable to find it again), instead I think the life of the thread is extended by being put on another thread.
Mike Ash has extensive articles on blocks, GCD and ARC which you may find useful:
Mike Ash: Practical Blocks
Mike Ash: Objective-C Blocks vs C++0x Lambdas: Fight!
Mike Ash: Q&A - More info on Blocks
Mike Ash: Automatic Reference Counting He talks about blocks & ARC in this article.
Mike Ash: GCD Is Not Blocks, Blocks Are Not GCD
Apple Docs - Introducing Block & GCD
This all looks good. Though, you might want to double-check the block parameter:
#property id myObject;
#property (copy) void (^myBlock)(NSString *);
....
- (void)testWithBlock: (void (^)(NSString *))block
{
NSString *testString = #"Test";
if (block)
{
block(test);
myObject = Block_copy(block);
myBlock = block;
}
}
...
[object testWithBlock: ^(NSString *test)
{
NSLog(#"[%#]", test);
}];
Should be fine. And I believe that they are even trying to phase out Block_copy(), but they haven't yet.
As the blocks programming topics guide says under 'Copying Blocks':
Typically, you shouldn’t need to copy (or retain) a block. You only need to make a copy when you expect the block to be used after destruction of the scope within which it was declared.
In the case you are describing, you can basically think about the block as simply being a parameter to your method, just like as if it were an int or other primitive type. When the method gets called, space on the stack will be allocated for the method parameters and so the block will live on the stack during the entire execution of your method (just like all the other parameters). When the stack frame gets popped off the top of the stack at the return of the method, the stack memory allocated to the block will be deallocated. Thus, during the execution of your method, the block is guaranteed to be alive, so there's no memory management to deal with here (in both ARC and non-ARC cases). In other words, your code is fine. You can simply call the block inside the method.
As the quoted text suggests, the only time you need to explicitly copy a block is when you want it to be accessible from outside of the scope where it was created (in your case, beyond the lifetime of the stack frame of your method). As an example, suppose you want a method that fetches some data from the web, and runs a block of code when the fetch is complete. Your method signature might look like:
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(void))completionHandler;
Since the data fetch happens asynchronously, you would want to keep the block around (likely in a property of your class) and then run the block once the data has been fully fetched. In this case, your implementation might look like:
#interface MyClass
#property (nonatomic, copy) void(^dataCompletion)(NSData *);
#end
#implementation MyClass
#synthesize dataCompletion = _dataCompletion;
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(NSData *fetchedData))completionHandler {
self.dataCompletion = completionHandler;
[self fetchDataFromURL:url];
}
- (void)fetchDataFromURL:(NSURL *)url {
// Data fetch starts here
}
- (void)finishedFetchingData:(NSData *)fetchedData {
// Called when the data is done being fetched
self.dataCompletion(fetchedData)
self.dataCompletion = nil;
}
In this example, using a property with a copy semantic will perform a Block_copy() on the block and copy it to the heap. This happens in the line self.dataCompletion = completionHandler. Thus, the block gets moved from the stack frame of the -getDataFromURL:completionHandler: method to the heap which allows it to be called later in the finishedFetchingData: method. In the latter method, the line self.dataCompletion = nil nullifies the property and sends a Block_release() to the stored block, thus deallocating it.
Using a property in this way is nice since it will essentially handle all of the block memory management for you (just make sure it's a copy (or strong) property and not simply a retain) and will work in both non-ARC and ARC cases. If instead you wanted to use a raw instance variable to store your block and were working in a non-ARC environment, you would have to call Block_copy(), Block_retain(), and Block_release() yourself in all the proper places if you wanted to keep the block around any longer than the lifetime of the method in which it's passed as a parameter. The same code above written using an ivar instead of a property would look like this:
#interface MyClass {
void(^dataCompletion)(NSData *);
}
#end
#implementation MyClass
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(NSData *fetchedData))completionHandler {
dataCompletion = Block_copy(completionHandler);
[self fetchDataFromURL:url];
}
- (void)fetchDataFromURL:(NSURL *)url {
// Data fetch starts here
}
- (void)finishedFetchingData:(NSData *)fetchedData {
// Called when the data is done being fetched
dataCompletion(fetchedData)
Block_release(dataCompletion);
dataCompletion = nil;
}
You know there are two kinds of blocks:
blocks stored in the stack, the ones that you explicitly write as ^{...}, and that disappear as soon as the function they are created in returns, just as regular stack variables. When you call a stack block after the function it belonged to has returned, bad things happens.
blocks in the heap, the ones that you get when you copy another block, the ones that live as long as some other object keeps a reference to them, just like regular objects.
The only reason for you to copy a block is when you are given a block that is, or may be a stack block (explicit local block ^{...}, or method argument whose origin you don't know), AND that you want to extend its life span out of the limited one of the stack blocks, AND that the compiler doesn't already do that job for you.
Think: keeping a block in an instance variable.
Adding a block in a collection such as NSArray.
Those are common examples of cases where you should copy a block when you're not sure it is already a heap block.
Note that the compiler does it for you when a block is called in another block.

can do anything during a callback ? a basic objective c issue

Sorry for the many posts here regarding this issue but i am having a progress here.
I have a callback function, which is in C , and been called when a new buffer is arrived.
I was told here to not do ANYTHING in that callback ,not malloc , or anything .
Now i want to send my new buffer to another class( which will create a circle buffer and save many buffers).
BUT, the basic thing that i dont get, is that if i call another function from the callback - its the same as doing it in there- becuase in that function i do the DSP and it takes time, so its the same as doing it in that callback- because its in serial.
froof :
i am sending the data to another function in another class, and its ok, but if i try to NSLOG it in there, i AGAIN have this memory leaks.
here is the other class that i call from the callback :
- (id)init
{
self = [super init];
if (self)
{
data = malloc (sizeof(SInt16) * 4000);
}
return self;
}
-(void)sendNewBuffer:(SInt16*)buffer
{
data=buffer;
NSLog(#"data arrived size is : %lu",sizeof(data));
for(int i=0; i<sizeof(data);i++)
{
NSLog(#"%d",data[i]);
}
}
ONLY when comment the log, it works without memory leaks.
that means the callback is waiting for that !
How would i process that data somwhere else in parallel ?
i am spending a week for that now.
thanks.
One possibility for the memory leak when using Objective-C objects such as the NSString in the NSLog is that those objects may be autoreleased (or may internally used autoreleased objects).
Your callback may be called from a different thread. You can confirm this by putting a breakpoint in the callback and looking in the debugger if this is the main thread or a secondary thread.
Any secondary thread must have its own AutoRelease pool. The system creates one automatically for the main thread, but you must create one explicitly if you are to create a secondary thread.
Also, one reason for not allocating stuff in a callback is usually for performances. Often the callback needs to be kept at minimum to avoid blocking the thread that called it.
I would suggest you read a C tutorial. There are at least two problems with your code which we can't really help you with:
data=buffer;: this leaks the previous value of data. You need to copy it to data (memcpy) or release the memory first (free) and then keep the pointer... unless the buffer goes out of scope after the callback, in which case your only option is to copy
sizeof(data): this can't work. data is a pointer; it doesn't know the amount of data that it being pointed at
The second means that you can't correctly implement the call back, at least not without further information. (Either the buffer has some indication of the volume of data or it's a constant size.)
If I had to guess (and I suppose I do) the callback is probably called in an interrupt context, hence malloc etc. would possibly be fatal.
What I would do is copy (ie. memcpy) the data to a buffer, and schedule/signal handling code to run later (eg. using condition variables, a runloop source, etc.)

Objective C: Memory management in Block cases

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
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).
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.
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.