Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在迭代之前复制集合是否足以防止同步问题?_Ios_Objective C_Multithreading_Synchronization - Fatal编程技术网

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可能不是线程安全的。即使您的集合访问得到了适当的保护,您也可能需要保护对这些对象的访问。

这似乎是非常常见的方法