Передача параметров в метод, вызываемый NSTimer - PullRequest
61 голосов
/ 25 октября 2010

Как передать параметр методу, вызываемому NSTimer? Мой таймер выглядит так:

[NSTimer scheduledTimerWithTimeInterval:4 target:self selector:@selector(updateBusLocation) userInfo:nil repeats:YES];

и я хочу иметь возможность передать строку в метод updateBusLocation. Кроме того, где я должен определить метод updateBusLocation? В том же файле .m, что я создаю таймер?

EDIT:

На самом деле у меня все еще есть проблемы. Я получаю сообщение об ошибке:

Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «* - [MapKitDisplayViewController updateBusLocation]: нераспознанный селектор отправлен в экземпляр 0x4623600»

Вот мой код:

- (IBAction) showBus {

//do something

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateBusLocation) userInfo:txtFieldData repeats:YES];
[txtFieldData release];
 }


 - (void) updateBusLocation:(NSTimer*)theTimer
 {
      NSLog(@"timer method was called");
      NSString *txtFieldData = [[NSString alloc] initWithString:(NSString*)[theTimer userInfo]];
if(txtFieldData == busNum.text) {
    //do something else
    }
    }

РЕДАКТИРОВАТЬ # 2: Не берите в голову, ваш пример кода работает хорошо, спасибо за помощь.

Ответы [ 6 ]

97 голосов
/ 25 октября 2010

Вам необходимо определить метод в цели. Поскольку вы устанавливаете цель как «себя», то да, этот же объект должен реализовывать метод. Но вы могли бы поставить цель на что-то еще, что хотели.

userInfo - это указатель, который вы можете установить для любого объекта (или коллекции), который вам нравится, и который будет передан целевому селектору при срабатывании таймера.

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: ... Простой пример:

Настройка таймера:

    NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
                              target:self 
                              selector:@selector(handleTimer:) 
                              userInfo:@"someString" repeats:NO];

и реализовать обработчик в том же классе (при условии, что вы устанавливаете цель как 'self'):

- (void)handleTimer:(NSTimer*)theTimer {

   NSLog (@"Got the string: %@", (NSString*)[theTimer userInfo]);

}
23 голосов
/ 24 января 2013

Вы можете передать свои аргументы с помощью userInfo: [NSDictionary dictionaryWithObjectsAndKeys:parameterObj1, @"keyOfParameter1"];

Простой пример:

[NSTimer scheduledTimerWithTimeInterval:3.0
                                 target:self
                               selector:@selector(handleTimer:)
                               userInfo:@{@"parameter1": @9}
                                repeats:NO];

- (void)handleTimer:(NSTimer *)timer {
    NSInteger parameter1 = [[[timer userInfo] objectForKey:@"parameter1"] integerValue];
}
4 голосов
/ 05 ноября 2018

Для Swift 4.0:

Вы можете иметь функцию с любыми параметрами, которые вы хотите, и использовать блок «scheduleTimer» для выполнения кода, который вам нужно повторить.

func someFunction(param1: Int, param2: String) {

    let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
        print(param1)
        print(param2)
    }
}

Будьте осторожны, чтобы вызывать timer.invalidate () , когда вы закончите, чтобы он не работал непрерывно.

3 голосов
/ 03 апреля 2015

Для Swift сделать вот так,

Например, вы хотите отправить UILabel с NSTimer

override func viewDidLoad() {
    super.viewDidLoad()

    var MyLabel = UILabel()
    NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("callMethod:"), userInfo: MyLabel, repeats: false)
}


 func callMethod(timer:NSTimer){

    var MyLabel:UILabel = timer.userInfo as UILabel

}
2 голосов
/ 22 сентября 2015

Дополнительный пример в Swift с использованием Литерал словаря для передачи параметров в метод, вызываемый NSTimer :

override func viewDidLoad() {
    super.viewDidLoad()

    let dictionary: [String : AnyObject] = ["first element" : "Jordan",
                                            "second element" : Int(23)]

    NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(0.41),
                                           target: self,
                                           selector: "foo:",
                                           userInfo: dictionary,
                                           repeats: false)
}

func foo(timer: NSTimer) {
        let dictionary: [String : AnyObject] = timer.userInfo! as! [String : AnyObject]
        let firstElement: String = dictionary["first element"] as! String
        let secondElement: Int = dictionary["second element"] as! Int
        print("\(firstElement) - \(secondElement)")
}
0 голосов
/ 19 июня 2018

Не прямой ответ на вопрос, но так как я столкнулся с этим во время поиска и мне нужно что-то другое, это может кому-то помочь.Я хотел вызвать funciton в классе помощника, который мне нужно было передать в UIViewController, а не передавать его с userinfo, что не позволило бы мне вызвать функцию вручную в другом месте, где я создал другую функцию, которую таймер будет вызывать иназывается функция, которая меня интересовала оттуда.Обходной путь, который помог.

Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.timerFired), userInfo: nil, repeats:true);

func timerFired() {

myFunction(controller: self)

}
...