代码之家  ›  专栏  ›  技术社区  ›  Joshua

在块iPhone SDK中引用self

  •  1
  • Joshua  · 技术社区  · 14 年前

    我试图植入一个回调机制,在该机制中,我将一个块传递给一个类的init,在完成一些工作后,该类将回调我。块被调用,而且大多数东西都可以工作,除非我在块内调用“self”上的任何东西。我得到了程序接收信号:exc_bad_访问,除非我注释掉块内对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;
    

    还尝试将块的声明向上移动到变量,并将其传入。每当我在Bock上使用“copy”时,都会得到相同的结果:我收到了可怕的程序接收信号:exc_bad_access。我想这可能是一个IOS3.2的东西,所以我试着在iPhone4.0模拟器下运行它,同样的结果。是否可能需要进行编译器设置才能将块“复制”到堆中?我用的是llvm1.5

    1 回复  |  直到 13 年前
        1
  •  4
  •   bbum    14 年前

    首先,什么是 blockSelf 在你的代码里?

    其次,不,你没有理由不能使用 self 这表示代码中有一个错误。

    具体来说,您没有复制块。块从堆栈开始。因此,当你说 theCallback = aCallback; ,您正在存储对堆栈上数据结构的引用。一旦定义堆栈帧消失,该结构就不再有效。

    变化 回拨=回拨; theCallback = [aCallback copy]; (并添加 [theCallback release]; 给你的 -dealloc 方法)。