【问题标题】:Passing parameters of method called by NSTimer传递由 NSTimer 调用的方法的参数
【发布时间】:2023-04-09 08:13:01
【问题描述】:

我有办法

 -(void)addFunction:(int)x andY:(int)y{
    countdown--;
     if(countdown == 0){
      NSLog(@"Your time expired");
      [myTimer invalidate];
        }
  else {
    int c = 0;
      c = x+y;
    NSLog(@"%i",c);
   }

   }

 -(void)RunTimer{
   countdown = 5; //countdown has been declared as a static variable so the whole class can access it in its current state.
   NSTimer * myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addFunction: :) userInfo:nil repeats:YES];
 }

现在我的问题是,addFunction 在我提供参数之前不会运行,否则它将打印 Null 值,我如何通过 NSTimer 调用具有参数的方法并发送这些参数?

【问题讨论】:

标签: ios


【解决方案1】:

查看以下代码,你需要更改addFunction的方法签名,并在userInfo中传递你想要的数据

-(void)addFunction:(NSTimer *)timer{

    NSDictionary *data = [timer userInfo]; 
    NSInteger x = [data[@"x"] integerValue];
    NSInteger y = [data[@"y"] integerValue];

    countdown--;
    if(countdown == 0){
        NSLog(@"Your time expired");
        [myTimer invalidate];
    }
    else {
        int c = 0;
        c = x+y;
        NSLog(@"%i",c);
    }

}

-(void)RunTimer{
    countdown = 5; //countdown has been declared as a static variable so the whole class can access it in its current state.

    NSDictionary *data = @{@"x" : @(5), @"y" : @(6)};

    NSTimer * myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addFunction:) userInfo:data repeats:YES];
}

【讨论】:

    【解决方案2】:

    我们可以这样做

    -(void)addFunction:(int)x andY:(int)y
    {
        countdown--;
        if(countdown == 0)
        {
            NSLog(@"Your time expired");
            [myTimer invalidate];
        }
        else {
            int c = 0;
            c = x+y;
            NSLog(@"%i",c);
        }
    
    }
    
    -(void)RunTimer
    {
        countdown = 5; 
        myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(callAddFunction) userInfo:nil repeats:YES];
    }
    -(void)callAddFunction
    {
        [self addFunction:10 andY:20];
    }
    

    【讨论】:

      【解决方案3】:

      编辑

      我喜欢其他答案中提供的解决方案;传递userInfo 字典中的变量。然而,OP 缺少一个基本概念,因为他不了解变量的范围,这一点在这一行的评论中有所揭示:

      countdown = 5; //countdown has been declared as a static variable so the whole class can access it in its current state.
      

      无论使用何种语言,都必须先了解变量的范围,然后才能有效地编程,所以这个问题更多的是关于变量范围而不是NSTimer及其调用方法。

      原始答案

      你只能向NSTimer调用的方法传递一个参数,那就是定时器本身的实例。

      因此,您需要考虑这些变量应该存在于何处,并且似乎将它们设为实例变量可能是最好的,也许使用类扩展。您也可以在那里存储NSTimercountdown 变量:

      @interface MyClass ()
      {
          int _x;
          int _y;
          NSTimer *_timer;
          int _countdown;
      }
      
      ...
      
      -(void)addFunction:(NSTimer *)timer
          _countdown--;
           if(_countdown == 0){
            NSLog(@"Your time expired");
            [_timer invalidate];
              }
        else {
          int c = 0;
            c = _x + _y;
          NSLog(@"%i",c);
         }
      
         }
      
       -(void)RunTimer{
         _countdown = 5;
         _timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                   target:self
                                                 selector:@selector(addFunction:)
                                                 userInfo:nil
                                                  repeats:YES];
       }
      

      使用全局变量是错误的,因为它将类的实例数限制为一个;不要这样做。

      【讨论】:

      • 我只是将倒计时用作全局变量,因为它需要访问倒计时的当前值。在这里,当被计时器调用时,x 和 y 是如何以及在哪里传递的?
      • @LightYagami 你不知道实例变量是什么,是吗?
      猜你喜欢
      • 2011-04-30
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多