我正在用目标C创建一个游戏,我被一个问题所阻止:我有一个警告,要求在@selector上传递多个变量。 我想要做的是在我的UIViewController中调用一个方法但是在延迟之后。所以我尝试制作第一种方法,在延迟之后调用另一种方法:
-(void)AnimationCoinInitWith_x:(int)x y:(int)y w:(int)w h:(int)h afterDelay:(NSTimeInterval)t
{
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
[self methodSignatureForSelector:@selector(AnimationCoinCopyInitWith_x:y:w:h:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(AnimationCoinCopyInitWith_x:y:w:h:)];
[invocation setArgument:x atIndex:1];
[invocation setArgument:y atIndex:2];
[invocation setArgument:w atIndex:3];
[invocation setArgument:h atIndex:4];
[NSTimer scheduledTimerWithTimeInterval:t invocation:invocation repeats:NO];
}
-(void)AnimationCoinCopyInitWith_x:(int)x y:(int)y w:(int)w h:(int)h
{
UIImageView* imageViewCoin = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, w, h)];
[imageViewCoin setAnimationImages:images];
[imageViewCoin setAnimationRepeatCount:1000];
[imageViewCoin setAnimationDuration:(1/24)];
[imageViewCoin startAnimating];
[self addSubview:imageViewCoin];
[imageViewCoin release];
}
但它不起作用,我不知道为什么。
感谢您的帮助!
答案 0 :(得分:4)
在这里,您的问题是NSInvocation
不会自动设置您需要的参数偏移量,并且所有objective-c方法都有两个不可见的参数(self
和_cmd
) ,你必须将参数索引偏移2而不是1。
这里的另一个问题是你没有通过引用传递参数,所以你必须使用地址运算符(&
):
[invocation setArgument:&x atIndex:2];
[invocation setArgument:&y atIndex:3];
[invocation setArgument:&w atIndex:4];
[invocation setArgument:&h atIndex:5];
一旦你这样做,上面的代码应该可以正常工作。
答案 1 :(得分:0)
作为一般规则,我们采用了避免NSInvocation的策略,除非绝对必要,因为代码往往难以阅读,易碎,并且在重构时会很头疼(以及错误的来源)。
此外,通过避免NSInvocation和使用简单的调用站点,编译器完全能够验证代码。
您可以使用“dispatch_after”模式:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self animationCoinInitWith_x: ...];
});
或者,如果你想坚持使用-performSelector:withObject:afterDelay :(我发现它更具可读性):
@interface Foo : NSObject
@end
@implementation Foo
- (void)invokeBlock:(dispatch_block_t)aBlock
{
aBlock();
}
- (void)doIt:(int)x toIt:(int)y
{
NSLog(@"%s %d %d", __PRETTY_FUNCTION__, x, y);
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
Foo* foo = [Foo new];
dispatch_block_t block = ^{
[foo doIt:10 toIt:10];
};
[foo performSelector:@selector(invokeBlock:) withObject:[block copy] afterDelay:5];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
以上假设为ARC(因此,缺乏发布)。