如何在主队列或线程上调度带参数的块

4
块是很棒的。因为我认为我了解它们,所以我想在更复杂的情况下使用它们。现在这些块正在踢我的脸,我正在尝试将其分解成可理解的部分。
假设我在这个伪代码中有两个块,方便地命名为blockAblockB。第一个是一个简单的无参数块,它只打印一行。第二个接受一个类型为id的参数xyz:
void (^blockA){ NSLog(@"Doing something"); };
void (^blockB)(id xyz){ [xyz doSomething]; };

运行blockA时,我会像这样做:blockA(); 或者当我想要针对主队列/线程时,我使用dispatch_sync_async方法:

dispatch_sync(dispatch_get_main_queue(), blockA);

虽然我知道如何使用像 blockB(someObject); 这样的参数来调度 blockB,但我不知道如何在主线程上显式调用它。我试图寻找类似下面这行代码的东西,但是当然,这并不是正确的方法:

dispatch_sync(dispatch_get_main_queue, blockB, someObject);

现在我尝试将该块包装在另一个块中,但说实话,这看起来并不对,并且感觉它引起了比解决更多的问题。除了包装块以分派一个或多个参数的块到主队列/线程之外,还有其他方法吗?

2个回答

19

不是的,在这种情况下,包装块级元素正是你需要做的事情。代码如下:

void (^block)(id someArg) = someBlock;
id object = someObject;
dispatch_async(dispatch_get_main_queue(), ^{
    block(someObject);
});

一开始看起来可能有点奇怪,但这种风格使得调度API变得更简单,自动保留捕获变量也成为可能。我有点惊讶你会遇到问题。你遇到了什么问题?


我遇到了一个可怕的网络锁死崩溃问题,但我无法追溯其起源:尝试从主线程或Web线程以外的线程获取Web锁。这可能是从辅助线程调用UIKit的结果。现在崩溃了... 这就是为什么我要分解这个问题,因为此时运行的任何代码都应该在主线程上运行。我以为嵌套块可能会导致这种情况,但根据你的说法,看起来是其他原因。 - epologee
仅在块中使用对象和我认为你想定义的是dispatch_async(dispatch_get_main_queue(), ^{ block(object);});有什么区别? - izzy

0

我也开始习惯使用代码块了。老实说,我认为没有比这更简洁/更好的写法了:

dispatch_async(dispatch_get_main_queue(), ^{blockb(someObj);});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接