0

Objective 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必要な引数のオフセットを自動的に設定しないことです。すべての目的 c メソッドには 2 つの目に見えない引数 (self_cmd) があるため、引数のインデックスを 1 ではなく 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 に答える