【问题标题】:Debugger reports value of BOOL block argument as NO, but my if statement evaluates true调试器将 BOOL 块参数的值报告为 NO,但我的 if 语句评估为 true
【发布时间】:2025-12-11 04:00:01
【问题描述】:

我正在调用一个带有布尔值的块。根据调试器,布尔值是假的,但它似乎被视为真。这是编译器/Xcode 错误,还是我应该以类似于__block 的方式标记传递给块的参数?

// Hovering over the |finished| parameter displays the value of finished as NO
[self.repDataSynchronizationClient synchronizeWithRepId:rep.id andCompletion:^(NSString * progressMessage, BOOL finished){
    if( finished )
    {
        [self hideLoader];    // Breakpoint set here, which I am hitting
    }
    else
    {
        [self setLoaderTitle:progressMessage];
    }
}];

这是a screenshot 的情况,显示了断点命中和工具提示。

【问题讨论】:

  • 另一种选择是它可能是调试器中的一个错误(即弹出窗口中显示的值可能是错误的)。
  • 我没有看到错误。弹窗说是NO,你也说是假的,矛盾在哪里?
  • @H2CO3 如果值为NO,则不应该通过if语句。
  • @aryaxt 调试器显示断点后的下一行,我还是没问题。
  • @JoshCaswell 与 XCode 错误有关的问题,而不是特别是代码。图片非常适合这个问题

标签: objective-c xcode debugging objective-c-blocks


【解决方案1】:

如果您是在发布而不是调试,则很有可能只是错误的断点。这可能是由于编译器删除了发布中的一些语句,如优化和行号不再与它们应该的代码对齐。

使用NSLog 语句验证您的 if 语句到达的子句。


在单独的说明中,您提到了__block 的使用,但实际上并没有使用它,并且似乎在那里有一个保留周期。它可能应该是:

__block id selfReference = self;
[self.repDataSynchronizationClient synchronizeWithRepId:rep.id andCompletion:^(NSString* message, BOOL finished) {
    if (finished)
    {
        [selfReference hideLoader];
    }
    else 
    {
        [selfReference setLoaderTitle:progressMessage];
    }
}];

如果使用 ARC,请使用 __unsafe_unretained 而不是 __block

【讨论】:

  • 感谢您的编辑,昨天我花了几个小时找出我的 ViewController 泄漏的原因,您的评论帮助修复了所有这些泄漏。我使用 __unsafe_unretained 而不是 __block
  • 很高兴我能帮上忙。 =] 我也将 ARC 引用添加到我的答案中
  • 这不一定是一个有问题的保留周期; 如果在self 之前不会释放块,则存在问题。由于这只是一个完成处理程序,因此 repDataSynchronizationClient 实际上是否在复制它是值得怀疑的。因此,它在堆栈上,一旦synchronizeWithRepId:andCompletion:完成,循环就会被打破。