Ios 在迭代之前复制集合是否足以防止同步问题?
我有一个Ios 在迭代之前复制集合是否足以防止同步问题?,ios,objective-c,multithreading,synchronization,Ios,Objective C,Multithreading,Synchronization,我有一个sessions属性,一个可变集。我需要迭代集合,但同时我可以用另一种方法更改集合: - (Session*) sessionWithID: (NSString*) sessionID { for (Session *candidate in _sessions) { /* do something */ } return nil; } - (void) doSomethingElse { [_sessions removeObject:
sessions
属性,一个可变集。我需要迭代集合,但同时我可以用另一种方法更改集合:
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in _sessions) {
/* do something */
}
return nil;
}
- (void) doSomethingElse
{
[_sessions removeObject:…];
}
这不是线程安全的。防弹版本将使用@synchronized
或调度队列来序列化\u会话
访问。但是,在迭代之前简单地复制集合有多合理呢
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in [_sessions copy]) {
/* do something */
}
return nil;
}
我不太在乎性能差异。在我的一个项目中,我有一个背景模拟,它是基于GLView绘制的。为了在背景线程中绘制,我需要复制模拟的当前帧数据,然后基于该数据执行绘制,以便模拟可以在其自身线程中继续,而不会扭曲图形数据
我认为异步使用的信息复制是完全有效的。尤其是在具有多核的设备中
@synchronize
会导致单独的线程停止(如果它们正在访问相同的信息),因此会导致比复制过程更大的性能损失。在我的一个项目中,我有一个后台模拟,GLView是基于此绘制的。为了在背景线程中绘制,我需要复制模拟的当前帧数据,然后基于该数据执行绘制,以便模拟可以在其自身线程中继续,而不会扭曲图形数据
我认为异步使用的信息复制是完全有效的。尤其是在具有多核的设备中
@synchronize
会导致单独的线程停止(如果它们正在访问相同的信息),因此可能会导致比复制过程更大的性能损失。我认为您的代码不是线程安全的,因为在复制时,集合可能会从另一个线程变异
您必须保护[\u sessions copy]
和[\u sessions remove object:…]
免受
同时执行
创建副本后,可以在不带锁的情况下对其进行迭代(假设集合元素本身不是从另一个线程修改的) 在我看来,您的代码不是线程安全的,因为在复制集合时,可能会从另一个线程对其进行变异 您必须保护
[\u sessions copy]
和[\u sessions remove object:…]
免受
同时执行
创建副本后,可以在不带锁的情况下对其进行迭代(假设集合元素本身不是从另一个线程修改的)
但是,在迭代之前简单地复制集合有多合理呢
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in [_sessions copy]) {
/* do something */
}
return nil;
}
如前所述,不能保证它是线程安全的。您需要保证\u会话
在-copy
期间不会发生变异。然后在不可变副本上迭代是安全的,\u sessions
的变异可能发生在次线程或您的实现中
在许多Cocoa集合的情况下,您会发现最好使用不可变IVAR和copy on set,方法是将属性声明为copy
,类型为NSSet
。这样,您可以在写入/设置时进行复制,然后避免在读取时进行复制。这有可能减少拷贝,具体取决于程序实际执行的方式。一般来说,仅此一点是不够的,您将需要更高级别的同步
还要记住,集合中的会话
s可能不是线程安全的。即使您的集合访问得到了适当的保护,您也可能需要保护对这些对象的访问
但是,在迭代之前简单地复制集合有多合理呢
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in [_sessions copy]) {
/* do something */
}
return nil;
}
如前所述,不能保证它是线程安全的。您需要保证\u会话
在-copy
期间不会发生变异。然后在不可变副本上迭代是安全的,\u sessions
的变异可能发生在次线程或您的实现中
在许多Cocoa集合的情况下,您会发现最好使用不可变IVAR和copy on set,方法是将属性声明为copy
,类型为NSSet
。这样,您可以在写入/设置时进行复制,然后避免在读取时进行复制。这有可能减少拷贝,具体取决于程序实际执行的方式。一般来说,仅此一点是不够的,您将需要更高级别的同步
还要记住,集合中的
会话
s可能不是线程安全的。即使您的集合访问得到了适当的保护,您也可能需要保护对这些对象的访问。这似乎是非常常见的方法