Objective c 没有正确使用NSLock,但似乎仍然有效

Objective c 没有正确使用NSLock,但似乎仍然有效,objective-c,cocoa,thread-safety,nslock,Objective C,Cocoa,Thread Safety,Nslock,我有线程安全问题。我有一个队列,当我修改内容时,它会导致线程间的错误。我以前没用过锁,但我想试试。我在操纵队列的备用NSMutableArray的所有代码周围添加了一个锁。我想问题是,我没有对所有的锁使用相同的锁。我在修改数组的每个方法中创建了一个新的NSLock实例。我假设我应该使用一个NSLock ivar来保护阵列。但我的困惑来自这样一个事实:一旦我添加了它,它就起作用了。下面是一个例子。我假设在创建新NSLock的任何地方,我都应该使用一个ivar NSLock。我认为这段代码只是锁定了

我有线程安全问题。我有一个队列,当我修改内容时,它会导致线程间的错误。我以前没用过锁,但我想试试。我在操纵队列的备用NSMutableArray的所有代码周围添加了一个锁。我想问题是,我没有对所有的锁使用相同的锁。我在修改数组的每个方法中创建了一个新的NSLock实例。我假设我应该使用一个NSLock ivar来保护阵列。但我的困惑来自这样一个事实:一旦我添加了它,它就起作用了。下面是一个例子。我假设在创建新NSLock的任何地方,我都应该使用一个ivar NSLock。我认为这段代码只是锁定了排队与其他排队的关系,以及排队与其他排队的关系,而不是排队与其他排队的关系。澄清一下就好了

@implmentation

...    

- (void)enqueue:(id)obj
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
   [_backingStore addObject:obj];
  [arrayLock unlock];
}

- (id)dequeue
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
  id result = [_backingStore firstObject];

  if( result )
  {
    [_backingStore removeObjectAtIndex:0];
  }

  [arrayLock unlock];
  return result;
}

...

@end

是的,您确实需要使用相同的NSLock实例来锁定对阵列的两次访问。与如此多的多线程错误一样,由于添加额外代码导致的时间差异,问题似乎已经消失。或者,可能只是你运气不好,第二次测试时问题没有出现

不管它值多少钱,NSLock只是锁定对Objective-C中关键部分访问的一种方式。您还可以使用
@synchronized()
,从代码复杂性的角度来看,这可能更容易:

@synchronized(someSharedToken) {
    // Do your array access here
}

您还可以使用串行调度队列来序列化对资源的访问。这有几个优点,其中最重要的一个是能够向它分派工作,而无需等待该工作在当前线程上完成。将工作分派到队列也比取出锁便宜。请参阅Apple的并发编程指南。

谢谢您的回答。我计划转到调度队列。我曾想过使用@synchronized,但认为它会为异常处理带来额外的开销。由于必须使用同一个实例,这是否意味着在我的示例中,如果两个线程调用enqueue方法,两个线程都不会实际阻止另一个,因为每个方法调用都会创建自己的实例?是的。我在这里举了一个又快又脏的例子,你可以看到这一点:。谢谢你的例子。