我正在使用一个库(快速图像缓存),它有一个方法可以接受一个可能同步或不同步调用的块。
我正在尝试使用以下代码确定块中的情况:
__block BoolSleeve* sync = [[BoolSleeve alloc] init];
sync.value = YES;
[object block:^{
if (sync.value)
NSLog(@"sync");
else
NSLog(@"async");
}];
sync.value = NO;
然而,到目前为止,这个和许多相关的变化都无法在预期时打印出“异步”。
BTW,BoolSleeve是:@interface BoolSleeve : NSObject
@property (assign, nonatomic) BOOL value;
@end
答案 0 :(得分:2)
正如文件中引用的那样:
如果请求的图像已存在于图像缓存中,则立即在当前线程上同步调用完成块。如果请求的图像在图像缓存中不存在,则只要请求的图像可用,就会在主线程上异步调用完成块。
鉴于上述信息,如果您希望确定它是在同一个线程上同步运行,还是在主线程上异步运行,您只需知道一件事:
图像当前是否存在于缓存中?
要查找,请调用对象的imageExistsForEntity:withFormatName:
方法。这样做会让您知道它是否存在于缓存中。有了这些信息,您就可以确定它是将在当前线程上同步运行,还是在主线程上异步运行。
我相信,您遇到的问题是,在调用阻止后,您正试图做出决定。到目前为止,无法让您知道,因为该框架不会向您提供有关此信息的任何信息。相反,您必须在方法调用之前确定。
因此,您的代码可能如下所示:
...
BOOL isSynchronousOnCurrentThread = [object imageExistsForEntity...];
...
[object block:^{
if (isSynchronousOnCurrentThread)
NSLog(@"Is Synchronous on current thread");
else
NSLog(@"Is Asynchronous on main thread");
}];
但是,要小心 - 框架开发人员可能稍后决定改变它。
,由于您将使用仅为框架所知的决策流程将您的代码与您的代码结合在一起,因此您的代码可能会中断。 注意:强>
要确定哪个是当前线程,您可以调用[NSThread currentThread]
。
暂且不谈: 我很好奇为什么你需要知道(因为我自己的黑暗和邪恶的原因)。也许有更好的方法来做你想要的,或者可能表明一个更大的问题。
答案 1 :(得分:1)
试试这个:
if ([NSThread isMainThread])
这将让您知道您正在运行的是否正在主线程上执行。如果没有,您可以在块之前和块中使用以下内容来获取每个的当前线程:
[NSThread currentThread]
然后你可以比较两者,看看他们是否是同一个线程。
答案 2 :(得分:-1)
你应该控制你如何调用你的块,它不应该在块范围内决定做什么。
Dispatch asynchronous:
void
dispatch_async(dispatch_queue_t queue, void (^block)(void));
Dispatch synchronous:
void
dispatch_sync(dispatch_queue_t queue, void (^block)(void));
e.g。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
// background operation
});
dispatch_sync(dispatch_get_main_queue(), ^{
// synchronous operation
});
dispatch_async(dispatch_get_main_queue(), ^{
// runs the block in the next run-loop on the main thread
});
您可以通过创建自己的队列并管理在其上发送的内容来获得更高级的效果,请参阅更多信息:https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man3/dispatch_queue_create.3.html#//apple_ref/doc/man/3/dispatch_queue_create