记住performSelector: 以便稍后在 Objective-C 中使用
在我的游戏的 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:
。有更好的方法解决这个问题吗?
编辑:
我尝试了两种方法,发现块更简单。我正在使用一个协议,所以我不确定如何处理这个问题(它总是返回一个 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];
In the box2d physics loop of my game (the step), I must call the following block:
if ([objectA conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectA performSelector:@selector(collideWith:) withObject:objectB];
}
if ([objectB conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectB performSelector:@selector(collideWith:) withObject:objectA];
}
The problem is that collideWith:
may alter my physics object and this isn't allowed during the step. Once the step is finished, the physics objects are free to be altered once more. I need some way to remember the target, selector and object paramater of this block for later use. One option would be to use a struct like this:
typedef struct {
id target;
SEL selector;
id object;
} FMCallback;
And store these in an array. Once I've finished my step, I then analyse this array and call performSelector:
. Is there a better way around this?
EDIT:
I tried both ways and found blocks to be simpler. I'm using a protocol, so I was unsure how to handle this (it would always return a 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];
It was also longer than I would have hoped. The blocks worked fine after some reading:
// 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];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许是一个
NSInspiration
?Perhaps an
NSInvocation
?块怎么样?
这是 ARC 的情况;如果没有 ARC,您可能应该在将块添加到数组时添加
copy
和autorelease
。How about blocks?
This is with ARC; without ARC you should probably add a
copy
andautorelease
when adding the blocks to the array.