2012-03-01 53 views
3

我试图通过使用unlockWithCondition(使用NSConditionLock)来绕过NSLock,但无论我得到相同的结果:iOS SDK - NSLock消息:“从未锁定的线程解锁”

*断开_NSLockError()进行调试。 * - [NSLock unlock]:lock('(null)')从未锁定的线程解锁。

我不确定是否it's不好,但什么I'm这样做是这样的:

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代码..” 可以执行。我不明白为什么我会得到这个错误。

任何人都可以解释我做错了什么?它看起来应该是完美的。

+0

有来自洛卡/ B在另一个线程调用? – 2012-03-01 16:56:08

+2

如果你在'_NSLockError()'上放置了一个断点,它会给你一个堆栈跟踪,显示出现非法解锁的位置。你尝试过吗? – user1118321 2012-03-01 18:31:36

+0

是的,我解析了请求在新线程上的响应。 – ZiggyST 2012-03-01 20:44:29

回答

6

我想你想在这里使用锁作为信号量。锁意味着阻止后台线程和主线程同时访问某些内容。因此,持有锁的线程也必须释放(解锁)它。

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

使用GCD信号灯为好,易于信号灯:https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

+1

是的,谢谢,我不知道ios是否有信号量,这就是为什么我使用nslock。 – ZiggyST 2012-03-06 14:45:10

+0

如果这个答案实际上扩展了上述场景对信号量的使用,那将是非常好的... – 2016-02-17 14:13:17

1

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

如果您确定您正在锁定主线程,则应该在该线程上解锁。在...空间

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

与您解锁:回到那里,你可以使用performSelectorOnMainThread:withObject:waitUntilDone:回调或GCD回调使用主线程。如果您在继续之前需要知道解锁已完成,则可以使用dispatch_sync()

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

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

不过,关键是你必须在同一个线程上锁定和解锁。

+0

非常感谢您的回答,我不是在同一个线程中解锁,为什么这是一个问题?这是锁的常用功能。,请等待其他人准备好 – ZiggyST 2012-03-01 20:43:39

+0

好吧,看到您已经尝试过NSCondition锁,我在上面添加了关于如何这样做的注释,而没有遇到该错误。 – gaige 2012-03-03 16:24:10

+0

感谢您的回答,但我无法将它从解锁它的线程中锁定。我做什么:我需要来自不同的HHTP请求的两个不同的值,所以请求,并锁定需要两个值的函数(在另一个线程中使用performSelectorInBackground :),然后当请求响应,我解析他们在不同的线程,并当他们完成解析,我解锁NSlock,所以另一个线程可以继续使用这些值。 PD:使用NSconditionLock,我有相同的错误信息。 – ZiggyST 2012-03-05 15:24:00