0

我正在目标 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];
}

但它不起作用,我不知道为什么。

谢谢你的帮助 !

4

2 回答 2

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];

一旦你这样做了,你上面的代码应该可以正常工作。

于 2013-03-12T13:53:24.177 回答
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(因此,缺少发布)。

于 2013-03-14T15:48:57.057 回答