objective-c - @synchronized 不适用于 NSMutableArray

标签 objective-c ios multithreading cocos2d-iphone

我正在尝试从一个可变数组中删除和对象 - 一个遍历每一帧的数组(参见刻度:方法)。

我正进入(状态

* Collection <__NSArrayM: 0xaa99cb0> was mutated while being enumerated.



异常(exception)。

所以我加了@synchronized()锁定它不被其他线程触及,但它仍然失败。
- (void)addEventSubscriber:(id <EventSubscriber>)eventSubscriber
{
     [_eventSubscribers addObject:eventSubscriber];
}

- (void)removeEventSubscriber:(id <EventSubscriber>)eventSubscriber
{
    @synchronized(_eventSubscribers) // Not working.
    {
       [_eventSubscribers removeObject:eventSubscriber];
    }
}

- (void)tick:(ccTime)dt
{
   for (id <EventSubscriber> subscriber in _eventSubscribers)
   {
       if ([subscriber respondsToSelector:@selector(tick:)])
       {
           [subscriber tick:dt];
       }
   }
}

最佳答案

您需要在迭代时完全锁定对数组的更新。将同步块(synchronized block)添加到两种方法 addEventSubscriber:removeEventSubscriber:将不起作用,因为数组可以在迭代时更改,因为迭代不同步。简而言之,一次只能运行这三种方法中的一种。

您可以使用 @synchronized ,或 NSLock在迭代时手动锁定数组更新。

或者,您可以将 GCD 与串行调度队列一起使用,以确保一次只执行一个方法。这是如何工作的:

您还可以将队列存储为您正在其中进行此处理的类对象的属性。

// Create the queue
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);

- (void)addEventSubscriber:(id <EventSubscriber>)eventSubscriber
{
    dispatch_sync(myQueue, ^{
        [_eventSubscribers addObject:eventSubscriber];
    });
}

- (void)removeEventSubscriber:(id <EventSubscriber>)eventSubscriber
{
    dispatch_sync(myQueue, ^{
       [_eventSubscribers removeObject:eventSubscriber];
    });
}

- (void)tick:(ccTime)dt
{
    dispatch_sync(myQueue, ^{
       for (id <EventSubscriber> subscriber in _eventSubscribers)
       {
           if ([subscriber respondsToSelector:@selector(tick:)])
           {
               [subscriber tick:dt];
           }
       }
    });
}

关于objective-c - @synchronized 不适用于 NSMutableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13676229/

相关文章:

iphone - iOS 应用程序窗口未初始化

ios - 检测 UIImageView 与任何对象的碰撞

java - 使用 rxjava 和 dagger2 跨线程访问 Realm

c# - 从正在运行的线程 C# 更改窗体的属性

ios - 如何在其他 View 生成之前完成一个 View 约束

iphone - 从 NSString 转换为 NSDate(即使你不知道 NSString 格式)

ios - Swift decodable 无法访问数组中的嵌套数据

ios - NSDateFormatter 在设置日期时没有给出正确的响应

ios - 使用动态大小的单元格限制 UICollectionView 的数量

python - 两个客户端没有成功连接到服务器