Reputation: 4997
Continuing to try to understand blocks in Objective-C. I have the following function:
typedef void(^TAnimation)(void);
TAnimation makeAnim(UIView *aView, CGFloat angle, CGFloat x, CGFloat y,
CGFloat width, CGFloat height, UIInterfaceOrientation uiio) {
return Block_copy(^{
aView.transform = CGAffineTransformMakeRotation(angle);
aView.frame = CGRectMake(x, y, width, height);
[UIApplication sharedApplication].statusBarOrientation = uiio;
});
}
When I try to do the following:
TAnimation f = makeAnim( ... );
f();
I get an EXC_BAD_ACCESS. However, if I do the following instead:
TAnimation f = makeAnim( ... );
[UIView animateWithDuration:0 delay:0 options:0 animations:f completion:NULL];
it works fine. What is the problem in the first scenario?
Upvotes: 3
Views: 899
Reputation: 1252
A very simple block-based example like this:
#import <Foundation/Foundation.h>
typedef void(^printerBlock)(void);
printerBlock createPrinter(NSString *thingToPrint) {
return Block_copy(^{
NSLog(@"Printing: %@", thingToPrint);
});
}
int main (int argc, char const* argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
printerBlock pb = createPrinter(@"Testing string.");
pb();
[pool drain];
return 0;
}
prints this out:
2011-10-22 21:28:14.316 blocker[12834:707] Printing: Testing string.
when I compile the program as "blocker", so there must be some other reason the direct block invocation is failing. Some reasons might be because the view you're passing in is being over-released, in which case the NSZombieEnabled advice will help you out.
If it's not the case that the view is being over-released, then you'll want to run this in the debugger and figure out exactly where things are falling over.
We'll probably have to see more of your code in order to figure out what's actually breaking.
Upvotes: 0
Reputation: 486
Try using NSZombieEnabled. When you deallocate an object it turns into a NSZombie, so when you call it, it throws an exception. To activate NSZombieEnabled, open the info window for the executable, go under Arguments and enter NSZombieEnable with a value of yes under "Variables to be set in the Environment:".
Upvotes: 1