@synchronized不能在NSMutableArray上工作

dai*_*dai 1 multithreading objective-c cocos2d-iphone ios

我试图从一个可变数组中删除和对象 - 一个遍历每一帧的数组(参见tick:方法).

我正进入(状态

*集合<__ NSArrayM:0xaa99cb0>在枚举时发生了变异.

例外.

所以我添加 @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];
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

Anu*_*rag 9

您需要在迭代时完全锁定数组的更新.向两个方法添加同步块addEventSubscriber:并且removeEventSubscriber:不起作用,因为迭代过程中数组可以更改,因为迭代未同步.简而言之,这三种方法中只有一种可以同时运行.

您可以在迭代过程中使用@synchronizedNSLock手动锁定阵列更新.

或者,您可以将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];
           }
       }
    });
}
Run Code Online (Sandbox Code Playgroud)