3

我使用 NSLock 遇到此错误,我试图通过使用 unlockWithCondition (使用 NSConditionLock)来规避它,但无论我得到相同的结果:

* 中断 _NSLockError() 以进行调试。* -[NSLock unlock]:锁('(null)')从没有锁定它的线程解锁。

我不确定它是否不好,但我正在做的是:

new Thread:
[lockA lock];//waiting unlock
[lockB lock];//waiting unlock
..shared code..
[lockA unlock];
[lockB unlock];

in Main Thread:
//Do two HTTP request.

//when request respond, I unlock the locks in respective threads with [lockA unlock];
[lockB unlock];

所以“..shared code..”部分可以执行。我不明白为什么我会收到此错误。

谁能解释我做错了什么?看起来它应该可以完美运行。

4

2 回答 2

7

我认为您正在尝试在这里使用锁作为信号量。锁是为了阻止后台线程和主线程同时访问某些东西。因此,持有锁的线程也必须释放(解锁)它。

如果您希望后台线程等待主线程上发生某些事情,请使用信号量。

使用 GCD 信号量来制作简单易用的信号量:https ://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

于 2012-03-05T16:04:47.623 回答
1

如果您在 NSURLConnection 或类似上执行 HTTP 请求并尝试在委托中解锁,则需要小心创建和启动 NSURLConnection 的位置,因为它应该返回到该线程,除非您明确使用scheduleInRunLoop:mode将其放在另一个线程上线程或运行循环。

如果您确定要锁定主线程,则应该在该线程上解锁。要回到那里,您可以使用performSelectorOnMainThread:withObject:waitUntilDone:回调或 GCD 来回调主线程,使用:

  dispatch_async(dispatch_get_main_queue(), ^(void) {
       ...
    });

随着您在 ... 空间中的解锁。dispatch_sync()如果您需要在继续之前知道解锁已完成,您可以使用。

但是,使用NSConditionLock, 正如您所指出的那样,您已经尝试过是解决方案。但是,您仍然需要在检索线程上进行锁定,而不是在主线程上。该条件将由您-unlockWithCondition:使用特定条件来保护,因此在检索线程将其标记为准备好之前它不会解锁。

因此,在您的主线程中,启动检索线程。在每个检索线程中,-lock然后继续检索数据,然后-unlockWithContidition:。在消费者线程中,使用-lockWhenCondition你应该没问题。

但是,关键是您必须在同一个线程上锁定和解锁。

于 2012-03-01T19:26:31.253 回答