首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当信号有两个不同的位置时如何使用NSCondition &等待

当信号有两个不同的位置时如何使用NSCondition &等待
EN

Stack Overflow用户
提问于 2014-03-31 13:10:17
回答 1查看 808关注 0票数 0

下面是我在方法中的伪代码:

代码语言:javascript
复制
NSCondition condition = [[NSCondition alloc] init];
int         predicate = 0;

dispatch_sync(dispatch_get_main_queue(), ^
{
    [condition lock];   // Lock-0
});

bindBlock1ForDataReceived(^()
{
    // Not main thread here.
    // Get on main thread, because lock and unlock must be run on same thread.
    dispatch_sync(dispatch_get_main_queue(), ^
    {
        predicate = 1;
        [condition signal];
        [condition unlock]; <<<<---- "unlocked when not locked"
    });
});

bindBlock2ForNoDataAvailable(^()
{
    // Not main thread here.
    // Get on main thread, because lock and unlock must be run on same thread.
    dispatch_sync(dispatch_get_main_queue(), ^
    {
        predicate = 2;
        [condition signal];
        [condition unlock];
    });
});

[condition lock];  // Lock-1
while (predicate == 0)
{
    [condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
}
[condition unlock];

if (predicate == 2)
{
    [condition lock];  // Lock-2
    [condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
    [condition unlock];
}

问题是,当第一个事件2发生时,当事件1发生时,我会从iOS获得一个“未锁定时解锁”警告(参见上文)。

现在,让我解释一下我要完成的任务:这是数据获取器的一部分。接收正常病例数据并执行block1 :没有问题。有时,非数据block2首先被伪造地执行,紧接着是block1;这是我收到NSCondition警告的时候。为了抓住这个罕见的情况,我等待2.0秒。下面是发生的事情:

  • Block2发出信号。
  • 锁-1掉了。
  • predicate不再是0,所以没有等待。
  • 条件又解锁了。
  • 然后我们继续到if-statement,它的条件是(predicate == 2)为真。
  • 该方法立即获得锁-2。<<<<的根本原因
  • 随后,该方法等待2.0秒。
  • 在这2秒内执行block1并向条件发出信号。
  • 然后,block1解锁条件&该方法也解锁。

根本原因(见上文)是,锁是通过方法(工作者/使用者)获得的,而它本应由数据生产者获得。我花了很多时间试图解决这个问题;我的想法之一是使用两个NSCondition,但我无法理解这一点,因为事情是交织在一起的。

注意:我觉得奇怪的是,这个警告没有出现在unlock中的if-statement中。

耽误您时间,实在对不起!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-23 12:02:46

除了锁定之外,最简单的方法是使用

代码语言:javascript
复制
dispatch_group_t confirmGroup = dispatch_group_create(); // 1

if (requestContacts) {
    dispatch_group_enter(confirmGroup); // 2
    [Extractor requestAccessAddressBook:^(BOOL isComplete) {
        if (isComplete) {
            dispatch_group_leave(confirmGroup); //2
        }
    }];


}
if (requestEvent) {
    dispatch_group_enter(confirmGroup); // 3       
    [Extractor requestAccessEvents:^(BOOL isComplete) {
        if (isComplete) {
            dispatch_group_leave(confirmGroup); // 3
        }
    }];
}
if (requestPhoto) {
    dispatch_group_enter(confirmGroup); // 4
    [Extractor requestAccessPhotos:^(BOOL isComplete) {
        if (isComplete) {
            dispatch_group_leave(confirmGroup); //4
        }
    }];
}
NSLog(@"dispatch_group_wait confirmations");
dispatch_group_wait(confirmGroup, DISPATCH_TIME_FOREVER); // 5
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22762438

复制
相关文章

相似问题

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