在 iPhone SDK 块中引用 self
我正在尝试实现一个回调机制,在该机制中我将一个块传递给一个类的 init,并在完成一些工作后该类将我回调。该块被调用并且几乎一切正常,除非我在块内调用“self”上的任何内容。我收到程序收到信号:“EXC_BAD_ACCESS”,除非我注释掉块内对 self 的任何引用。
我认为我可以在块内访问 self 是错误的吗? 任何建议将不胜感激。这段代码位于一个全新的“通用应用程序”中,我目前正在处理 iPad 部分,因此在 iPad 模拟器下运行。
一些代码:
__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];
}];
这是来自 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;
}
和回调调用,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (theCallback) {
theCallback(self);
}
}
我更改为以下代码行,
theCallback = aCallback;
另一件事是
theCallback = [aCallback copy];
向我显示以下错误
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
,我的块的定义如下所示
typedef void(^loginClicked)(LoginAlertView*);
,成员变量是这样的
loginClicked theCallback;
还尝试将块的声明移至变量,并将其传递进去。这具有相同的结果每当我在块上使用“副本”时,我都会收到可怕的程序接收信号:“EXC_BAD_ACCESS”。我想这可能是IOS3.2的东西,所以我尝试在iPhone 4.0模拟器下运行它,结果相同。是否可能需要进行编译器设置才能将块“复制”到堆上?我使用的是LLVM1.5
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您的代码中的
blockSelf
是什么?其次,不,您没有理由不能使用
self
,这表明您的代码中存在错误。具体来说,您没有复制该块。块从堆栈开始。因此,当您说
theCallback = aCallback;
时,您正在存储对堆栈数据结构的引用。一旦定义的堆栈帧消失,该结构就不再有效。将
theCallback = aCallback;
更改为theCallback = [aCallback copy];
(并将[theCallback release];
添加到您的-dealloc< /代码> 方法)。
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;
totheCallback = [aCallback copy];
(and add[theCallback release];
to your-dealloc
method).