NSLock实例应该是“全局的”吗?

时间:2009-10-17 16:21:30

标签: iphone core-data multithreading locking nslock

我应该在应用程序委托中创建一个NSLock实例,供所有类使用吗?或者是否建议让每个类根据需要实例化自己的NSLock实例?

例如,如果我有权访问分布在两个视图控制器上的托管对象上下文,那么锁定是否会在第二种情况下工作?

2 个答案:

答案 0 :(得分:4)

如果多个对象仅访问您的对象以读取其内容,则根本不需要锁定。如果至少有一个对象访问您的对象以写入/更新其内容,那么其他对象是否访问您的对象以读取或写入/更新它并不重要:在这种情况下,您需要锁定。

现在,为了正确保护您的对象(在多个对象可以访问它的代码的关键部分),您必须使用SAME LOCK INSTANCE,然后必须由访问您对象的所有可能对象共享愿意保护。

如果您的应用程序需要保护可能被大多数类同时访问的对象,那么拥有一个锁定实例就可以了。如果您想获得更好的性能(特别是如果同时访问对象的数量很高),那么您可以拥有多个锁。每个锁将负责允许/拒绝访问对象的特定属性/字段。这样,多个对象可以访问您的对象同时更改不同的属性/字段。您基本上是在增加对象的并发操作数。但是,每个锁必须仍然在将访问您正在保护的对象的其他对象之间共享。

为每个控制器设置一个锁定实例根本不起作用;这不会保护您的对象免受来自不同线程中其他对象的并发访问。 NSLock是使用POSIX pthread互斥锁实现的,因此必须以完全相同的方式使用它。 NSLock文档中也明确说明了这一点:

警告:NSLock类使用POSIX线程来实现其锁定行为。向NSLock对象发送解锁消息时,必须确保从发送初始锁定消息的同一线程发送消息。从另一个线程解锁锁定可能导致未定义的行为。

因此,为了保留临界区语义,它是获取锁的同一个线程,负责在完成时释放它。另请注意,锁定机制仅用于快速操作,即您应在释放之前仅在短时间内获得锁定。如果您需要等待不可预测的时间,那么您需要一个不同的同步机制,即通过NSCondition类可用的条件变量。

希望这有帮助。

答案 1 :(得分:1)

您不应该使用带有Core Data的锁。该文档可能已过时。理想情况下,您应该有一个上下文每个线程并让上下文处理其底层NSPersistentStoreCoordinator的锁定。这被认为是目前在多线程应用程序中使用Core Data的唯一安全方式。