4

プロジェクトのインスタンス変数にブロックを格納しようとしています。インスタンス変数を宣言する場所は次のとおりです。

@property (nonatomic, copy)void (^loginCompletedTask)();

このメソッドを呼び出して変数を割り当てています。

- (void)requireLoggedInForBlock:(void (^)())completion {
    self.loginCompletedTask = completion;

    // Display an alert view that requires username and password input
}

このメソッドの最初の行の後、self.loginCompletedTask非 nil で、 type でデバッガーにログインしますNSMallocBlock。しかし、ログイン警告ビューが返された後に実際にブロックを実行する必要がある場合、それは nil になっています。

私はもう試した:

  • strongの代わりにcopy, で宣言する
  • として設定しself.loginCompletedTask = ^{completion();};
  • プロパティ ( ) を使用する代わりに、変数を直接設定します_loginCompletedTask = ...

私は何が欠けていますか?

4

2 に答える 2

1

ブロックを誤って保存することとは何の関係もないことが判明しました。実際には、ブロックを格納したものと同じクラスの新しいオブジェクトを作成していましたが、実際のブロックをコピーするのを忘れていました。したがって、値をログアウトしたヒットされたメソッドは、self.loginCompletedBlock最初に変数を割り当てたオブジェクトではなく、他のオブジェクトによって受信されていました。

助けてくれてありがとう、SOユーザーが喜んで助けてくれることにいつも驚かされます。

于 2013-08-19T15:35:19.990 に答える
1

ブロックは、ヒープではなくスタック上に作成される (これまでのところ) 唯一のオブジェクトです。ブロックが作成されたスタック フレームの寿命よりも長くブロックを保持したい場合はcopy、ブロックする必要があります (コピーはヒープ ベースです)。強力なポインターを使用しても、スタック フレームがポップされたときにブロックが消えるのを止めることはできません。

追加: コメントは正しく、コピー プロパティがあれば十分です。悪いことに、コピー属性がそこにあるのを忘れていました。

于 2013-08-19T15:18:49.643 に答える