0

调用 dispatch_async 时出现代码问题。我认为这个问题是由于 ARC 在将对象用于块之前回收对象,因为调度它的方法完成。

- (void) method:(SomeClass *) someClass {
  // local variable
  NSNumber *someValue = someClass.somePropertyOnManagedObject;
  dispatch_async(queue, ^() {
    /* call some singleton object passing variable 
     * when access the variable, reference is nil
     */
    [[DashboardFacade sharedInstance] someMethod:someValue];
  });
}

在浏览了很多文档后,我得出结论

  • 块访问没有参数 - 没有什么可讨论的
  • 块访问简单的类型参数,例如 BOOL、int - 这些是复制的,不是问题
  • 块访问调度它的方法的参数 - 我不确定,但认为这没关系
  • 块访问 self 的属性——只要 self “活着”直到调用正常完成
  • 块在分派它的方法中访问局部变量
    • 如果我们使用一些信号量,这样我们在离开方法之前等待块返回,那么一切都好
    • 否则变量可能在块可以使用之前已被垃圾收集。

我认为解决方案是使用__block修饰符使 ARC 保留变量。

我的问题是

  • 以上在技术上是否正确,例如使用__block将解决问题而不引入其他问题?
  • 为什么我在互联网/谷歌的任何地方都找不到这个?
4

2 回答 2

0

someValue仅当在此分配之后它为 nil 时,块内部才能为 nil:

NSNumber *someValue = someClass.somePropertyOnManagedObject;

由于在块内使用了这些变量,块会保留被块捕获的对象。它是 self 还是块可见范围内的局部变量都没有关系。

于 2014-01-17T14:53:31.217 回答
0

以上在技术上是否正确,例如使用 __block 将解决问题而不引入其他问题?

是的,它在技术上是正确的__block,在 ARC 上,允许您更改在NSNumber *块上下文之外声明的变量(在本例中为它指向的位置,因为它是 a )。

为什么我在互联网/谷歌的任何地方都找不到这个?

我认为问题与代码的这个特定位置无关,而是与其他问题有关。

于 2014-01-17T14:10:50.370 回答