1

クラスの初期化にブロックを渡すコールバックメカニズムを実装しようとしています。いくつかの作業の後、そのクラスが私を呼び出します。ブロックが呼び出され、ブロック内の「self」で何かを呼び出す場合を除いて、ほとんどすべてが機能します。ブロック内で自分自身への参照をコメントアウトしない限り、Program received signal: “EXC_BAD_ACCESS” が表示されます。

ブロック内で自分自身にアクセスできると考えるのは間違っていますか? アドバイスをいただければ幸いです。このコードは、新しい「ユニバーサル アプリ」に含まれており、現在、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

もう1つ、私のブロックの定義は次のようになります

typedef void(^loginClicked)(LoginAlertView*);

そしてメンバー変数はこれです

loginClicked theCallback;

また、ブロックの宣言を変数に移動して、それを渡そうとしました。これは同じ結果になりました。ブロックで「コピー」を使用するたびに、恐ろしいプログラム受信信号「EXC_BAD_ACCESS」が表示されます。これはおそらく IOS3.2 のものだと思ったので、iPhone 4.0 シミュレーターで実行してみましたが、同じ結果でした。ブロックをヒープに「コピー」するために必要なコンパイラ設定はありますか? 私はLLVM1.5を使用しています

4

1 に答える 1

4

まず、blockSelfあなたのコードには何がありますか?

第二に、いいえ、使用できない理由はありませんself。これは、コードにバグがあることを示しています。

具体的には、ブロックをコピーしていません。ブロックはスタックから始まります。したがって、 と言うときはtheCallback = aCallback;、スタック上のデータ構造への参照を格納しています。定義スタック フレームがなくなるとすぐに、その構造は無効になります。

に変更theCallback = aCallback;しますtheCallback = [aCallback copy];(そしてメソッドに追加[theCallback release];します-dealloc)。

于 2010-07-02T15:47:13.790 に答える