首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >某些设备上的`dispatch_semaphore_wait()`有问题吗?

某些设备上的`dispatch_semaphore_wait()`有问题吗?
EN

Stack Overflow用户
提问于 2013-10-10 21:57:21
回答 1查看 3K关注 0票数 0

我正在使用开源软件TMCache。它为异步缓存节省了昂贵的数据。还有一个同步方法。

它使用dispatch_semaphore_wait()来等待操作结束。

https://github.com/tumblr/TMCache/blob/master/TMCache/TMCache.m#l288

代码语言:javascript
复制
- (id)objectForKey:(NSString *)key
{
    if (!key)
        return nil;

    __block id objectForKey = nil;

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    [self objectForKey:key block:^(TMCache *cache, NSString *key, id object) {
        objectForKey = object;
        dispatch_semaphore_signal(semaphore);
    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    #if !OS_OBJECT_USE_OBJC
    dispatch_release(semaphore);
    #endif

    return objectForKey;
}

这个在我的机器上运行得很好。但在同事的机器上却没有。该程序在dispatch_semaphore_wait()停止工作。对我来说这绝对是不可复制的。

上述方法在tableView:viewForTableColumn:row:中调用,

所以它在主队列中执行。

知道为什么会这样吗?必须在另一个队列中使用该方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-11 18:48:07

很可能你的线程用完了。应该释放dispatch_semaphore_signal()的dispatch_semaphore_wait()需要在一个新线程中执行(参见objectForKey:block:有关详细信息)。如果OS未能分派新线程,您就会陷入困境,因为没有人会向您发送dispatch_semaphore_signal。

它发生的频率和时间取决于计算机/设备的速度,你滚动表格的速度等等。这就是为什么你不能在你的电脑上复制这个问题。

这里的快速解决方案是通过使用相同的调度信号量方法(将超时设置为DISPATCH_TIME_NOW )来保持线程数低,因为您可能不会阻塞主队列。

不过,我更喜欢改变TMCache.m的工作方式。我认为,在这种情况下,调度信号量方法是不合理的--以牺牲可靠性为代价获得代码简洁(将异步方法包装为同步对应)对我来说似乎是不对的。我曾经用异步方法包装同步方法,但反之亦然。

这是解决办法

https://github.com/rushproject/TMCache

请注意,只修补了同步objectForKey方法。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19306934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档