问题
I created a block, inside a delegate method and I am using it to call a static method in another class. I am getting an EXC_BAD_ACCESS error even when I have NSZombies enabled. There are a few posts on here about similar problems - I think this one is the closest:
ARC: Getting EXC_BAD_ACCESS from inside block used in delegate method
But, I haven't found anything so far that has helped. Here is the code:
@interface MyClass()
@property (nonatomic, copy) CaseBlock c;
@end
....
//NSURLConnection delegate method
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:
//blows up after executing this
^() { [AnotherClass staticMethod]; },authURL,
^() { NSLog(@"TODO");}, searchURL,
^() { NSLog(@"TODO"); }, itemURL,
nil];
self.c = [[d objectForKey:[self.url path]] copy];
if (self.c) {
self.c();
} else { NSLog(@"WARN unexpected response path"); }
}
This is the first time that I have tried to use blocks, but I can tell that this is causing the problem because calling the method from outside the block works fine. And also, as far as I can tell, all of the code that I wrote actually gets executed AND THEN the EXC_BAD_ACCESS error happens. But, I am new to Objective-C so, please correct me if I am wrong about that.
回答1:
You need to copy blocks if they need to outlive the scope they were created in. Since dictionaryWithObjectsAndKeys:
deals with objects in general and not specifically blocks, it doesn't know to copy them, so you must copy them before passing them to it.
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:
//blows up after executing this
[^() { [AnotherClass staticMethod]; } copy], authURL,
[^() { NSLog(@"TODO");} copy], searchURL,
[^() { NSLog(@"TODO"); } copy], itemURL,
nil];
来源:https://stackoverflow.com/questions/14744378/arc-exc-bad-access-when-calling-a-method-from-inside-a-block-inside-a-delegate