简体   繁体   English

在块IPhone SDK中引用self

[英]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. 我正试图建立一个回调机制,我将一个块传递给一个类的init,并在该类调用我之后进行了一些工作。 The block gets called and most everything works, except when I call anything on "self" within the block. 块被调用,大多数都可以工作,除非我在块中的“self”上调用任何东西。 I get Program received signal: “EXC_BAD_ACCESS” unless I comment out any reference to self within the block. 我得到程序接收信号:“EXC_BAD_ACCESS”,除非我在块中注释掉对self的任何引用。

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. 这段代码是一个全新的“通用应用程序”,我目前正在研究IPad部分,因此在IPad模拟器下运行。

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 这是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”. 还尝试将块的声明移动到一个变量,并将其传入。这具有相同的结果无论何时我在块上使用“复制”我得到可怕的程序接收信号:“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. 我想也许这是一个IOS3.2的东西,所以我尝试在iPhone 4.0模拟器下运行它,结果相同。 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 我正在使用LLVM1.5

First, what is blockSelf in your code? 首先,代码中的blockSelf是什么?

Secondly, no, there is no reason why you can't use self and this is indicative of a bug in your code. 其次,不,没有理由不能使用self ,这表明代码中存在错误。

Specifically, you aren't copying the block. 具体来说,您不是在复制块。 Blocks start out on the stack. 块从堆栈开始。 Thus, when you say theCallback = aCallback; 因此,当你说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; 改变theCallback = aCallback; to theCallback = [aCallback copy]; to theCallback = [aCallback copy]; (and add [theCallback release]; to your -dealloc method). (并将[theCallback release];添加到-dealloc方法中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM