xco*_*der 6 multithreading objective-c nsmutablearray
我有一个包含许多对象的NSMutableArray.
如果对数组进行了更改会发生什么,而我使用[NSMutableArray arrayWithArray:someArray]制作数组的副本;
例如:如果一个对象在复制过程中从数组中删除了一个对象?
我不确定如何测试这种情况.
编辑:对象未释放(因为它们保留在其他地方).我只是将这个数组用作查找表.
jus*_*tin 11
如您所知,容器/集合不保证是线程安全的.如果您在复制或阅读时更改阵列会发生什么?很多东西.显而易见的情况是它可能在当时重新分配,它可能传递或返回对您的无效引用(例如最近删除的),或者它可能访问已释放的对象(来自另一个线程).除了会导致您的应用崩溃或导致其他UB的事情,它可能无法返回正确或一致的值.这是对数据的误解.两者都不好.
你不测试场景 - 线程问题难以重现,你真的无法涵盖所有情况.由于对象本身并不保证线程安全 - 您的实现必须一次限制对一个线程的访问/突变/交互.处理多线程上下文中使用的对象时:无论何时从对象的可变状态访问或查询信息,都应该保护对象(例如,使用锁定).因此,您只需在使用时锁定它.锁定/复制/解锁/使用副本也很常见.对于NSMutableArray,可变状态的示例将是其所有对象及其计数.它的操作和突变也使用对象的可变状态,因此它们受到限制.
如果你只从一个线程使用这个对象,那么显然不需要锁定它.这也是为什么在大多数情况下通过复制和保存不可变变体都是好主意的原因.你不需要锁定每个对象,保存它的对象的保护通常是设计线程安全类的好方法.
更新
...怎么了?该副本是否包含所有5个对象(因为它们仍保留在其他地方?它们是否包含4个?(即使包含4个对我来说足够了)是否抛出异常?
如果你没有妥善保护这个系列,它就像未定义的行为一样好,如果它崩溃你就很幸运.
您需要采取适当的预防措施,以避免未定义的行为.当你的程序没有得到妥善保护时,你的程序就在该域中运行.
详细说明:在外部保留对象只会降低未定义行为的概率,但它肯定不会消除它.更多的后果示例包括异常,段错误,读取或写入内存,这些内存被用作另一个主动分配(可能显示为非常神秘的问题,也可能几乎不可能重现).
我鼓励你正确防范或采取其他方法.UB是EVIL :)
来自Apple的文档:
可变对象通常不是线程安全的.要在线程应用程序中使用可变对象,应用程序必须使用锁同步对它们的访问.(有关更多信息,请参阅"原子操作").通常,当涉及到突变时,集合类(例如,NSMutableArray,NSMutableDictionary)不是线程安全的.也就是说,如果一个或多个线程正在更改同一阵列,则可能会出现问题.您必须锁定发生读写的位置,以确保线程安全.
也来自Apple的文档:
虽然"原子"意味着对属性的访问是线程安全的,但只是让你的类中的所有属性都是原子的并不意味着你的类或更一般的对象图是"线程安全的" - 线程安全无法在个人访问方法的级别.有关多线程的更多信息,请参阅"线程编程指南".
归档时间: |
|
查看次数: |
3066 次 |
最近记录: |