views:

67

answers:

1

I'm trying to implament a callback mechanism where I pass in a block to the init of a class, and after some work that class calls me back. The block gets called and most everything works, except when I call anything on "self" within the block. I get Program received signal: “EXC_BAD_ACCESS”. unless I comment out any reference to self within the block.

Am I wrong to think that I can access self within the block? any advice would be greatly appreciated. This code is in a brand new "Universal app" and I'm currently working on the IPad portion, so running under the IPad simulator.

some code...

__block LoginViewController *blockSelf = self;
    LoginAlertView *alert = [[LoginAlertView alloc] 
                         intWithPinPrompt:NO 
                         title:@"Mobile Login"
                         myCallback:^(LoginAlertView *v){
                             DLog(@"self %@", blockSelf);
                             NSString *u = v.userNameText;
                             NSString *p = v.passwordText;
                             NSString *i = v.pinText;
                             [self authenticateUser:u
                                           password:p
                                                pin:i];
                         }];

and here is the some code from the LoginAlertView

- (id) intWithPinPrompt:(BOOL)pinPromptEnabled title:(NSString*)aTitle myCallback:(loginClicked)aCallback{
if (self = [self initWithTitle:aTitle
                       message:nil 
                      delegate:self 
             cancelButtonTitle:@"Cancel" 
             otherButtonTitles:@"Login", nil]) {
    hasPinPrompt = pinPromptEnabled;
    theCallback = aCallback;
}
return self;

}

and the callback call

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (theCallback) {
    theCallback(self);
}

}

I changed to following line of code

theCallback = aCallback;

to

theCallback = [aCallback copy];

which is presenting me with the following error

Program received signal:  “EXC_BAD_ACCESS”.

(gdb) bt

0 0x029c8c97 in objc_msgSend ()

1 0xbfffe560 in ?? ()

2 0x00026f66 in -[LoginViewController show] (self=0x4a38450, _cmd=0x209c36c) at LoginViewController.m:18

3 0x00026d3b in -[AuthenticatedViewController viewWillAppear:] (self=0x4c1fac0, _cmd=0x20b59ac, animated=0 '\0') at AuthenticatedViewController.m:17

one other thing, the definition of my block looks like this

typedef void(^loginClicked)(LoginAlertView*);

and the member variable is this

loginClicked theCallback;

also tried moving the declaration of the block up to a variable, and passing that in. this had the same results Anytime I use the "copy" on the bock I get the dreaded Program received signal: “EXC_BAD_ACCESS”. I thought maybe this was a IOS3.2 thing, so I tried running it under the IPhone 4.0 simulator, same results. Is there possibly a compiler setting that needs to be made in order to "Copy" the block onto the heap? I'm using LLVM1.5

+2  A: 

First, what is blockSelf in your code?

Secondly, no, there is no reason why you can't use self and this is indicative of a bug in your code.

Specifically, you aren't copying the block. Blocks start out on the stack. Thus, when you say theCallback = aCallback;, you are storing a reference to an on-stack data structure. As soon as the defining stack frame goes away, that structure is no longer valid.

Change theCallback = aCallback; to theCallback = [aCallback copy]; (and add [theCallback release]; to your -dealloc method).

bbum
thanks for your response bbumI have a line of code just before the call to LoginAlert alloc that says __block LoginViewController *blockSelf = self;I was trying to see if the problem was something to do with self not being mutable, and from what I read unless you use __block variables on the stack are only available as "Const" within the block. I know self isn't defined on the stack, but I thought it was worth a shot.When i add your line of code "the copy" to the init of the LoginAlertView I get the followingProgram received signal: “EXC_BAD_ACCESS”.
Joshua
It is the block that starts on the stack and that is the issue. Did you copy the block correctly (I had a mistake in my answer; copying theCallback and not aCallback)?
bbum
Oh, and, got backtrace?
bbum
added as "answer" to get code formatting, and allow more then 500 chars
Joshua