【发布时间】:2010-12-28 11:04:07
【问题描述】:
在Obj-C中,简单来说是什么意思; “CoreData 不是线程安全的”
或者一般来说什么是“非线程安全”?
【问题讨论】:
标签: iphone objective-c multithreading nsthread
在Obj-C中,简单来说是什么意思; “CoreData 不是线程安全的”
或者一般来说什么是“非线程安全”?
【问题讨论】:
标签: iphone objective-c multithreading nsthread
@d11wtq 的回答是正确的只有在编写自己的代码或设计自己的 API 时。
在使用一组 API 时这是完全错误的,而在使用 Core Data 时则完全错误。
在使用 Mac OS X 和 iOS 的环境中,必须始终在使用系统 API 的环境中考虑线程安全。即使使用 NSArray 也意味着您正在使用系统 API。
或者一般来说什么是“非线程” 安全吗?
非线程安全 API 是您无法同时从多个线程与 API 交互的 API。可能还存在最常涉及主线程的其他限制。例如,几乎所有的绘图操作都必须发生在 Mac OS X 和 iOS 的主线程上。
Apple 文档假定线程安全是例外情况。也就是说,只有在文档明确声明线程安全的情况下,API 才是线程安全的。如果没有提到线程安全,则必须假定 API 不是线程安全的。
在 Obj-C 中,简单是什么意思 条款; “CoreData 不是线程安全的”
这种说法并不完全正确,但它是一个安全的假设。
在Core Data的情况下,线程交互行为是extremely well documented。
简而言之,API 的某些部分是线程安全的(例如存储协调器),而某些部分显然不是线程安全的。虽然 MOC 提供了锁定和解锁方法,但您可以也使用外部锁定。但是不要。它的效率会更低,也更脆弱;明显如此。一般来说,也不要使用内部锁定。 CoreData 针对每个线程/队列有一个上下文进行了优化。
(根据 TC 的反馈修复了答案。谢谢。)
【讨论】:
更新 |请参阅@bbum 的回答。我接受我的回答有缺陷并且@bbum 是正确的。
如果某些内容被描述为“非线程安全”,则意味着没有采取任何特殊预防措施来确保在两个单独的线程同时尝试使用它时它不会崩溃。通常,要被多个线程使用的代码需要显式锁定(或@synchronize 块)围绕代码的各个方面。特别是,任何将被修改的对象/变量几乎肯定会导致崩溃,如果两个线程碰巧同时写入它(因为它们将写入相同的内存地址)。类似地,如果一个线程正在读取一个变量而另一个线程正在写入它,则会返回垃圾并且程序可能会崩溃。
使用@synchronized、NSLock 或 POSIX 互斥锁等可确保在任何给定时间只有一个线程可以执行特定的代码块。其他线程被阻塞,必须等到锁被释放。使用锁对性能有轻微影响(当然还有一些开发开销必须考虑它们),所以代码经常明确声明它不是线程安全的,让你,代码的采用者,自己根据需要放置锁(或将非线程安全的执行限制为单个线程)。
有关线程和线程安全的更多信息,请参阅 Apple 文档:
【讨论】: