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是非零并使用 type 登录调试器NSMallocBlock。但是,当我实际需要在登录警报视图返回后运行该块时,它已变为 nil。

我试过了:

  • strong用而不是声明copy
  • 设置为self.loginCompletedTask = ^{completion();};,
  • 直接设置变量,而不是使用属性 ( _loginCompletedTask = ...)。

我错过了什么?

4

2 回答 2

1

块是在堆栈而不是堆上创建的唯一对象(迄今为止)。如果你想让一个块比创建它的堆栈帧的生命周期更长,你必须copy使用这个块(副本是基于堆的)。当堆栈帧被弹出时,即使使用强指针也不会阻止块消失。

补充:评论是正确的,有一个复制属性就足够了。我的错,我忘记了复制属性在那里。

于 2013-08-19T15:18:49.643 回答
1

事实证明,它与错误地存储块无关。我实际上是在创建一个与存储块但忘记复制实际块的对象相同类的新对象。因此,被命中的注销 值的self.loginCompletedBlock方法被另一个对象接收,而不是被分配变量开始的对象。

感谢大家的帮助,SO 用户如此愿意提供帮助总是让我感到惊讶。

于 2013-08-19T15:35:19.990 回答