在我的游戏的 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: 。有没有更好的方法来解决这个问题?

编辑:

我尝试了两种方法,发现块更简单。我正在使用协议(protocol),所以我不确定如何处理这个问题(它总是返回一个 nil 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];

最佳答案

块呢?

NSMutableArray *collisions = [NSMutableArray array];
…
[collisions addObject:^{
    [objectA collideWith:objectB];
}];
…
for (id collision in collisions)
    ((dispatch_block_t)collision)();

这是 ARC;如果没有 ARC,您应该在将块添加到数组时添加 copyautorelease

关于objective-c - 记住 performSelector : for later in Objective-C,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9053662/

10-13 03:31