我正在尝试从一个可变数组中删除和对象 - 一个遍历每一帧的数组(参见刻度:方法)。
我正进入(状态
* 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/