referencing self within a block IPhone SDK
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)aCall开发者_如何学JAVAback{
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
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).
精彩评论