为GCD调用写宏?

时间:2012-02-24 18:15:35

标签: ios xcode macros grand-central-dispatch

我想为GCD调用创建一个宏,例如:

dispatch_async(dispatch_get_main_queue(), ^{
    stuff....
});

宏可能看起来像这样: 主(^ {...})?

不确定如何写它。有什么建议吗?

谢谢

2 个答案:

答案 0 :(得分:11)

建议:不要。除此之外,它还会在调试中搞砸行号。

你可以实际定义一个普通的函数,如果你愿意,可以做同样的事情,比如

typedef void(^VoidBlock)();
void on_main(VoidBlock block) {
    dispatch_async(dispatch_get_main_queue(), block);
}

这样做的好处是在调试期间不会丢失块的行号。我甚至做过像

这样的事情
void on_main(VoidBlock block) {
  if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
    block();
  } else {
    dispatch_sync(dispatch_get_main_queue(), block);
  }
}

我可以从主队列调用,也可以不调用。

确实想避免将代码块放在宏参数中。如果您必须调试该代码,那么您会讨厌自己。 (有点舌头,但如果你必须调试任何扩展到多行代码的宏,那真的很痛苦。)

答案 1 :(得分:3)

您可以像这样定义宏:

#define ASYNC(...) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __VA_ARGS__ })
#define ASYNC_MAIN(...) dispatch_async(dispatch_get_main_queue(), ^{ __VA_ARGS__ })

第一个将在未指定的线程上异步调用代码(使用它执行所有长时间运行的任务),第二个将在主线程上异步调用块(使用它执行所有与UI相关的操作)。

你可以将两者结合起来。假设您想从网络中获取内容并更新UI,您可以写:

ASYNC({
  NSString *result = [[NSString alloc] initWithContentsOfURL: ...];
  ASYNC_MAIN({
    self.myTextField.string = result;
    [result release];
  });
});

添加花括号以使Xcode正确缩进代码。

请注意保留/释放呼叫的位置。这是一种强大的技术,可以使您的代码可读。