For some reason I want a block to execute during the next iteration of the run loop, so I came up with:
typedef void (^resizer_t)() ;
- (void) applyResizer: (resizer_t) resizer {
resizer() ;
Block_release(resizer) ;
}
- (void) usage {
...
resizer_t resizer = ^() {
// stuff
} ;
[self performSelectorOnMainThread:@selector(applyResizer:)
withObject:(__bridge id) Block_copy((__bridge void *) resizer)
waitUntilDone:NO] ;
}
The code seems to work, I didn't detect a leak nor a premature release, but I'm a bit puzzled by the syntax ...
Block are treated as objects so ARC prevent you from casting them to void *
without explicit bridged cast. It strange that your compiler doesn't complain on Block_release
: it should (on my machine, it does).
Because ARC treats block as objects, you shouldn't need to use Block_copy
nor Block_release
anymore. Copy the block (with -[NSObject copy]
) when you want it to move to the heap and let the compiler manage the remainder.
-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]
retains the receiver and the parameter object until the method is invoked. So your block will be retained and released when required. All you have to do is ensure that the block isn't stored on the stack by sending the copy
message before passing it to the method.
Moreover, there is a simpler way to dispatch the execution of a block: it's libdispatch (aka GCD).
dispatch_async(dispatch_get_main_queue(), resizer);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With