CoreData 不是线程安全的是什么意思?
在Obj-C中,简单来说是什么意思; “CoreData 不是线程安全的”
或者一般来说什么是“不是线程安全的”?
In Obj-C, what does it mean in simple terms;
"CoreData is not thread safe"
OR in general what is "not thread safe" ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
@d11wtq 的答案只有在编写自己的代码或设计自己的 API 时才是正确的。
在使用一组 API 时,这是完全错误的,在使用 Core Data 时,这是完全错误的。
在使用 Mac OS X 和 iOS 的环境中,必须始终在使用系统 API 的环境中考虑线程安全。即使使用 NSArray 也意味着您正在使用系统 API。
非线程安全 API 是指您无法同时从多个线程与 API 进行交互的 API。还可能存在通常涉及主线程的附加限制。例如,几乎所有绘图操作都必须在主线程上进行。 Mac OS X 和 iOS 上的线程
安全是例外情况,也就是说,只有在文档明确声明线程安全的情况下,API 才是线程安全的。线程安全,你必须假设API不是线程安全的。
这个说法不太正确,但它是一个安全的假设。
在 Core Data 的情况下,线程交互行为是 非常详细的记录。
简而言之,API 的一部分是线程安全的(例如,存储协调器),而一部分则非常明确地不是线程安全的。虽然 MOC 提供锁定和解锁方法,但您也可以使用外部锁定。但不要。它的效率会更低,也更脆弱;显然如此。一般情况下,也不要使用内部锁定。 CoreData 针对每个线程/队列都有一个上下文进行了优化。
(根据 TC 的反馈修复了答案。谢谢。)
@d11wtq's answer is correct only when writing your own code or designing your own APIs.
It is entirely incorrect when working with a set of APIs and quite specifically wrong when working with Core Data.
In the context of working with Mac OS X and iOS, thread safety must always be considered in the context of working with the system APIs. Even using, say, an NSArray means that you are working with the system APIs.
A non-thread safe API is an API where you cannot interact with the API from multiple threads simultaneously. There may also be additional restrictions that most often involve the main thread. For example, almost all drawing operations must occur on the main thread on both Mac OS X and iOS.
The Apple documentation assumes thread safety is the exceptional case. That is, an API is only thread safe if the documentation explicitly claims thread safety. If there is no mention of thread safety, you must assume that the API is not thread safe.
That statement is not quite correct, but it is a safe assumption.
In Core Data's case, the thread interaction behavior is extremely well documented.
In short, parts of the API are thread safe (the store coordinator, for example) and parts are quite explicitly not thread safe. While the MOC provides lock and unlock methods, you can also use external locking. But don't. It will be less efficient and more fragile; significantly so. In general, don't use the internal locking either. CoreData is optimized around having a context per thread/queue.
(Answer fixed based on TC's feedback. Thanks.)
更新 |请参阅@bbum的回答。我承认我的答案有缺陷,@bbum 是正确的。
如果某些东西被描述为“非线程安全”,则意味着没有采取特殊的预防措施来确保在两个单独的线程尝试同时使用它时它不会崩溃。一般来说,由多个线程使用的代码需要显式锁定(或 @synchronize 块)来包裹代码的各个方面。特别是,如果两个线程碰巧同时写入任何对象/变量,则几乎肯定会导致崩溃(因为它们将写入相同的内存地址)。类似地,如果一个线程正在读取变量,而另一个线程正在写入变量,则将返回垃圾并且程序可能会崩溃。
使用 @synchronized 或 NSLock 或 POSIX 互斥体等,可确保在任何给定时间只有一个线程可以执行特定的代码块。其他线程被阻塞并且必须等待直到锁被释放。使用锁会对性能造成轻微影响(当然还有一些必须考虑它们的开发开销),因此代码经常明确声明它不是线程安全的,让代码的采用者根据需要自己放置锁(或将非线程安全的执行限制为单个线程)。
有关线程和线程安全的更多信息,请参阅 Apple 文档:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocThreading.html#//apple_ref/文档/uid/TP30001163-CH19-BCIIGGHG
UPDATE | Please see @bbum's answer. I accept that my answer is flawed and @bbum is correct.
If something is described as "not thread safe", it means that no special precautions have been taken to ensure it won't crash should two separate threads try to use it simultaneously. In general, code that is to be used by more than one thread requires explicit locks (or
@synchronize
blocks) wrapping around aspects of the code. In particular, any object/variable that will be modified would almost certainly cause a crash if two threads happened to write to it at the same time (since they'd be writing to the same memory address). Similarly, if one thread was reading a variable while another was writing to it, garbage would be returned and the program would likely crash.Using
@synchronized
, orNSLock
or a POSIX mutex etc, ensures that only one thread can execute a particular block of code at any given time. The other threads get blocked and have to wait until the lock is released. There is a slight performance hit with using locks (and of course some development overhead having to think about them), so often code expressly declares that it is not thread safe, leaving you, the adopter of the code, to place locks as needed yourself (or limit execution of the non thread-safe to a single thread).See the Apple documentation for more information about threading and thread safety:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocThreading.html#//apple_ref/doc/uid/TP30001163-CH19-BCIIGGHG