使用局部变量调用dispatch_async时的内存问题

时间:2014-01-17 13:37:34

标签: ios objective-c dispatch-async

调用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];
  });
}

在查看了大量文档之后,我总结了

  • Block访问无参数 - 无需讨论
  • 块访问简单类型参数,例如BOOL,int - 这些是复制而不是问题
  • 块访问调度它的方法的参数 - 我不确定,但想一想 这没关系
  • 阻止访问自己的属性 - 只要自己“活着”直到通话结束就可以了
  • Block在调度它的方法中访问局部变量
    • 如果我们使用一些信号量,以便我们在离开方法之前等待块返回,那么一切正常
    • 否则变量可能在块可以使用之前被垃圾收集。

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

我的问题是

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

2 个答案:

答案 0 :(得分:0)

  

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

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

  

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

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

答案 1 :(得分:0)

只有在此赋值后它为零时,块内的

someValue才能为零:

NSNumber *someValue = someClass.somePropertyOnManagedObject;

由于在块内使用这些变量,块会保留块捕获的对象。如果它是自身或来自块可见范围的局部变量并不重要。