web-dev-qa-db-fra.com

Comment appeler une méthode toutes les x secondes dans Objective-C en utilisant NSTimer?

J'utilise Objective-C, Xcode 4.5.1 et je travaille sur une application pour iPhone.

J'ai une méthode A dans laquelle je veux appeler une autre méthode B pour faire une série de calculs toutes les x secondes. Dans la méthode A, je commence à lire un fichier audio. La méthode B surveillera l'audio toutes les x secondes pendant la durée du fichier audio.

J'ai trouvé NSTimer comme solution potentielle, mais j'ai du mal à le faire fonctionner/à le comprendre.

Je veux simplement appeler la méthode B toutes les x secondes et exécuter ses calculs, mais NSTimer me demande de fournir plusieurs choses dont je ne suis pas sûr de ce que je suis censé lui dire.

[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval) 
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];

Je comprends qu'à NSTimeInterval je fournis l'intervalle auquel je veux que NSTimer fonctionne. Mais, comment puis-je lui dire d'exécuter la méthode B?

J'ai regardé un exemple de code et j'ai actuellement l'impression de fournir la méthode sur le 'select: '. Mais, qu'est-ce que j'écris au 'target: '? Pourquoi aurais-je besoin d'une cible? J'ai essayé d'entrer 'self', mais Xcode me dit:

Utilisation de l'identifiant non déclaré "self"

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self 
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];

Donc, je suppose que 'self' est censé être un pointeur vers un objet, mais où veux-je pointer?

Voici une simplification de mon code:

MethodA()
{
//Start playing an audio file.

//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}

MethodB()
{
//Do calculations.
}

Je serais reconnaissant si quelqu'un pouvait me fournir des réponses/me diriger dans la bonne direction! (:

23
RoelfMik

La cible est le destinataire du message nommé dans select. Dans Objective-C, les fonctions ne sont pas appelées. Il y a plutôt des messages envoyés aux objets. L'objet fait référence en interne à sa table de symboles et détermine laquelle de ses méthodes est appelée. C'est un sélecteur. Votre sélecteur est @selector(MethodB). (BTW: vous devez commencer les noms de méthode en minuscules. "MethodB" serait plus approprié ici.) Cela conduit à la question: comment déterminer l'objet auquel le message est envoyé? Voilà l'objectif. Dans votre cas, c'est simplement self.

BTW: Dans ce cas, le sélecteur doit retourner void et accepter un identifiant, qui est l'identifiant de l'objet NSTimer lui-même. Cela vous sera utile si vous souhaitez que la minuterie arrête de tirer en fonction de certaines conditions en fonction de la logique de votre programme. Plus important: votre sélecteur est alors methodB: plutôt que methodB.

- (void) methodA
{
//Start playing an audio file.

//NSTimer calling Method B, as long the audio file is playing, every 5 seconds.
[NSTimer scheduledTimerWithTimeInterval:5.0f 
target:self selector:@selector(methodB:) userInfo:nil repeats:YES];
}

- (void) methodB:(NSTimer *)timer
{
//Do calculations.
}
40
Hermann Klecker

essaye ça

 NSTimer *aTimer = [NSTimer timerWithTimeInterval:(x) target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

    NSRunLoop *runner = [NSRunLoop currentRunLoop];
    [runner addTimer:aTimer forMode: NSDefaultRunLoopMode];  
    [popUpImageView release];

- (void)timerFired:(NSTimer*)theTimer 
{
if(condition)
{
  [theTimer isValid]; //recall the NSTimer
   //implement your methods
}
else
{
  [theTimer invalidate]; //stop the NSTimer

}

}
6
NANNAV

Eh bien, vous essayez d'appeler une méthode C normale, NSTimer ne peut pas le faire.

La cible est l'instance de la classe sur laquelle appeler le sélecteur , ce sélecteur ne sélectionne pas. Le sélecteur ici est un type SEL que vous pouvez créer avec la fonction @selector(METHOD_NAME).

Par exemple, cela appellera le handleTimer : toujours 0,1 seconde: (Pour cet exemple, l'AppDelegate est utilisé):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //SNIP, some code to setup the windos.   

    [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
    return YES;
}

- (void) handleTimer:(NSTimer *)timer {
    // Hanlde the timed event.
}
5
rckoenes

Si vous regardez votre code et comparé à celui ci-dessous

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];

self signifie que vous invoquez une méthode dans la même instance de votre classe, dans votre exemple, la méthode est myVolumeMonitor

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

et vous êtes prêt à partir

la méthode devrait ressembler à ceci

- (void)MethodB:(NSTimer*)timer { 
// do something
}
4
CodeBro