【问题标题】:dispatch_queue_t need to be released using dispatch_release()?dispatch_queue_t 需要使用 dispatch_release() 释放吗?
【发布时间】:2012-02-23 23:04:16
【问题描述】:

我有两个异步的 GCD 块。第一个用于后台线程,第二个在主线程上运行。这很好用,但我刚刚看到某处说我可能需要使用dispatch_release() 释放它们。例如:

// Use gcd
dispatch_queue_t queue = dispatch_queue_create("com.awesome", 0);
dispatch_queue_t main = dispatch_get_main_queue();

//  do the long running work in bg async queue
// within that, call to update UI on main thread.
dispatch_async(queue, ^{ 
   // Do work in the background



    // Release
    dispatch_release(queue);

   dispatch_async(main, ^{ 

       // Main


       // Release
       dispatch_release(main);

   });//end
});//end

这是真的吗?我需要在这里释放它们吗?

【问题讨论】:

  • 根据头文件中的 cmets,您需要在您创建的任何队列上调用 dispatch_release()。

标签: objective-c ios objective-c-blocks grand-central-dispatch


【解决方案1】:

您只需要释放使用dispatch_queue_create 创建的队列。主队列永远存在,释放它没有意义。

添加到队列中的任何块都将保留队列本身,因此您可以在调用dispatch_async 之后安全地调用dispatch_release(queue)。最好在您在这里编写代码之后在块之外执行此操作。

【讨论】:

  • 好的,但是如果我在队列之外进行,它不会自动释放吗?
  • @NicHubbard 它会在队列的所有工作完成后释放,例如您可以创建一个队列,向其分派 3 - 4 个块,并在分派调用后释放它。队列将一直保留,直到所有块都完成了相应的任务。此时您不再需要此队列。
【解决方案2】:

仅释放您创建的队列;不要释放主队列或全局并发队列(或者,再一次,任何你自己没有创建的队列)。正如您所做的那样,将发布嵌套在该队列中排队的工作块中也不是一个好主意,因为这是在错误的范围内进行的,并且:

queue = dispatch_queue_create(...)
dispatch_async(queue, ^{ something; dispatch_release(queue); });
dispatch_async(queue, ^{ something else}); // CRASH!

当您稍后更改代码以添加第二个 dispatch_async() 时将无法正常工作。假设可以,始终将您的创建/发布调用配对在同一范围内,这是一个更好的风格选择。

【讨论】:

  • 好的,所以我只需要在 dispatch_asynch 调用之外释放它?
  • 是的。具体来说,您需要在与 create 调用相同的范围内执行此操作,以免您为自己设置一个地雷,以便稍后踩到,正如我在回答中所说明的那样(此规则的唯一例外可能是终结器,但我们不要混淆事物:))
猜你喜欢
  • 2014-02-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 2012-01-22
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多