2013-03-12 4 views
0

Я создаю игру в объективе C, и меня останавливает вопрос: у меня есть предупреждение о передаче нескольких переменных на @selector. Что я хочу сделать, это вызов метода в моем UIViewController, но после задержки. Так что я пытаюсь сделать первый метод, который называют другой после задержки, как это:Несколько параметров для @selector

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

После того, как вы сделаете это, ваш код выше, должен работать нормально ,

+0

У меня есть предупреждение с этим кодом: Несовместимое целое число для преобразования указателя, передающего 'int' в параметр типа 'void *'; – user2057209

+0

@ user2057209 Правильно, я просто понял это. Обновлен мой ответ. –

+0

Похоже на работу, у меня есть ошибка для плохого доступа, но ваш код работает! Благодаря !! =) – user2057209

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 (следовательно, отсутствие выпусков).

 Смежные вопросы

  • Нет связанных вопросов^_^