Przekazywanie parametrów do metody wywołanej przez NSTimer

Jak mogę przekazać parametr do metody wywołanej przez NSTimer? Mój timer wygląda tak:

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

I chcę móc przekazać łańcuch do metody updateBusLocation. Również, gdzie mam zdefiniować metodę updateBusLocation? W tym samym .plik m, który tworzę timer?

EDIT:

Właściwie wciąż mam problemy. Otrzymuję komunikat o błędzie:

Zamykanie aplikacji z powodu nieautoryzowanego wyjątku 'NSInvalidArgumentException', powód: '* -[MapKitDisplayViewController updateBusLocation]: nierozpoznany selektor wysłany do instancji 0x4623600 '

Oto Mój kod:

- (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
    }
    }

EDIT # 2: Nieważne, Twój przykładowy kod działa dobrze dzięki za pomoc.

Author: Keavon, 2010-10-25

5 answers

Musisz zdefiniować metodę w celu. Ponieważ ustawiasz cel jako 'self', to tak, że ten sam obiekt musi zaimplementować metodę. Ale mogłeś ustawić cel na cokolwiek innego.

UserInfo jest wskaźnikiem, który można ustawić na dowolny obiekt (lub kolekcję) i który zostanie przekazany do selektora docelowego podczas wywołania timera.

Mam nadzieję, że to pomoże.

EDIT:... Prosty Przykład:

Ustaw timer:

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

Oraz zaimplementuj obsługę w tej samej klasie (zakładając, że ustawiasz cel na 'self'):

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

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

}
 96
Author: Firoze Lafeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-05 06:17:17

Możesz przekazać swoje argumenty za pomocą userInfo: [NSDictionary dictionaryWithObjectsAndKeys:parameterObj1, @"keyOfParameter1"];

Prosty przykład:

[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];
}
 23
Author: Oleh Kudinov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 17:12:51

For Swift do like this,

Na przykład chcesz wysłać UILabel z 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

}
 3
Author: Zaid Pathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-03 06:24:11

Dodatkowy przykład w Swift używając dosłownego słownika do przekazania parametrów do metody wywołanej przez 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)")
}
 2
Author: King-Wizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 01:22:14

Nie jest to bezpośrednia odpowiedź na pytanie, ale ponieważ natknąłem się na to podczas wyszukiwania i potrzebowałem czegoś innego, może to komuś pomóc. Chciałem wywołać funciton w klasie pomocniczej, którą musiałem przekazać w UIViewController, zamiast przekazywać go za pomocą userinfo, które nie pozwalało mi na ręczne wywołanie funkcji w innym miejscu, stworzyłem inną funkcję, którą wywoływał timer i wywołał funkcję, którą byłem stamtąd zainteresowany. Obejście, które pomogło.

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

func timerFired() {

myFunction(controller: self)

}
 0
Author: Sam Bing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 14:43:52