В физическом цикле box2d моей игры (шаг) я должен вызвать следующий блок:
if ([objectA conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectA performSelector:@selector(collideWith:) withObject:objectB];
}
if ([objectB conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectB performSelector:@selector(collideWith:) withObject:objectA];
}
Проблема в том, что collideWith:
может изменить мой физический объект, и это не разрешеново время шага.Как только шаг закончен, физические объекты могут быть изменены еще раз.Мне нужен какой-то способ запомнить целевой объект, селектор и параметры этого блока для последующего использования.Одним из вариантов будет использование такой структуры:
typedef struct {
id target;
SEL selector;
id object;
} FMCallback;
и сохранение их в массиве.Когда я закончу свой шаг, я проанализирую этот массив и вызову performSelector:
.Есть ли лучший способ обойти это?
РЕДАКТИРОВАТЬ:
Я попробовал оба способа и нашел блоки, чтобы быть проще.Я использую протокол, поэтому я не был уверен, как с этим справиться (он всегда будет возвращать ноль NSMethodSignature):
NSMethodSignature *sig = [FMObject instanceMethodSignatureForSelector:@selector(collideWith:)];
NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:sig];
invoc.target = objectB;
invoc.selector = @selector(collideWith:);
[invoc setArgument:objectA atIndex:2];
[Presenter.physics.callbacks addObject:invoc];
Это также дольше, чем я надеялся.После некоторого чтения блоки работали нормально:
// In the collision
[Presenter.physics.callbacks addObject: Block_copy(^{
[(id)objectB collideWith:objectA];
})];
// After the step
for (id collision in callbacks_) {
((dispatch_block_t)collision)();
Block_release(collision);
}
[callbacks_ removeAllObjects];