这是我在方法中的伪代码:
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:没有问题。有时,无数据块 2 会首先被虚假执行,紧接着是块 1;这是我收到NSCondition
警告的时候。为了抓住这种罕见的情况,我等了2.0
几秒钟。这是发生的事情:
- Block2 发出条件信号。
- Lock-1 落空。
predicate
不再是0
所以没有等待。- 条件再次解锁。
- 然后我们继续到
if
条件(predicate == 2)
为真的-语句。 - 该方法立即获得 Lock-2。<<<< 根本原因
- 随后该方法等待
2.0
几秒钟。 - 在这 2 秒内 block1 被执行并发出条件信号。
- 然后 block1 解锁条件和方法也解锁。
根本原因(见上文)是锁是由方法(工作者/消费者)获取的,而它应该是由数据生产者获取的。我花了很多时间试图弄清楚这一点。我的一个想法是使用两个NSCondition
s,但我无法弄清楚这一点,因为事情是相互交织的。
注意:我觉得奇怪的是警告没有出现在-statementunlock
内部。if
谢谢你的时间!