0 votes

Délégués et plusieurs méthodes

J'ai un problème que j'ai résolu en utilisant des délégués, mais maintenant je pense que j'ai peut-être commis une erreur.

Voici ce que je veux faire.

J'ai une classe qui s'exécute avec un délai. Quand elle a fini, elle appelle un délégué terminé.

Maintenant j'ai la classe principale qui crée deux de ces classes de délai.

Je ne veux pas qu'elles soient toutes les deux gérées par la même méthode isfinished dans la classe principale. Je veux en utiliser deux différentes.

Cependant, je crois qu'avec la méthode du protocole de création de délégués, cela ne fonctionnera pas pour moi.

Y a-t-il une solution à cela?

delayclass setdelegates MainclassFunction1
delayclass setdelegates MainclassFunction2

5voto

Joshua Nozzi Points 38718

Si je vous ai bien compris, jetez un œil au protocole NSTableViewDelegate. Là, le premier argument de chaque méthode du délégué est l'instance de NSTableView envoyant le message.

Vous pouvez résoudre votre problème en modifiant vos méthodes de délégué pour que l'objet délégué s'envoie lui-même en argument. Ensuite, dans votre délégué, vous feriez quelque chose comme ceci :

if (theDelegator == objectA)
{
    // Faire quelque chose
}

if (theDelegator == objectB)
{
    // Faire quelque chose d'autre
}

Ainsi, vous avez une méthode de délégué parfaitement implémentée qui peut gérer plusieurs objets le déléguant.

1voto

Ciarán Walsh Points 1586

Comme mentionné, les méthodes de délégation couramment incluraient l'objet initié le rappel, de sorte que vous pouvez les différencier de cette façon. Alternativement, vous pouvez également avoir l'objet envoyer une notification, ce qui rendra également l'originateur disponible.

1voto

Ranumao Points 101

Utiliser des délégués ne semble pas être la bonne approche pour moi; ils sont généralement utilisés pour augmenter le comportement. Ce qui semble le plus approprié ici est le motif cible/sélecteur, comme NSTimer.

@interface MyObject : NSObject {
@private
    id target;
    SEL selector;
}
@property(assign) id target;
@property SEL selector; /* Le sélecteur doit renvoyer void et accepter un argument, qui est l'instance MyObject ayant invoqué la méthode. */
@end

@implementation MyObject
- (void)notifyTarget {
    [[self target] performSelector:[self selector] withObject:self];
}
@synthesize target;
@synthesize selector;
@end

C'est généralement l'approche la plus propre car le rappel du délégué n'a pas besoin de désambiguïser l'expéditeur. Utiliser des notifications semble être trop lourd pour un problème de ce domaine.

0voto

Pourquoi n'utilisez-vous pas simplement NSTimer, en ajoutant différents timers et en les faisant appeler les sélecteurs que vous aimez dans la classe que vous utilisez comme délégué maintenant?

Quelque chose comme:

NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(myMethod1:) userInfo:nil repeats:YES];

NSTimer *timer2 = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(myMethod2:) userInfo:nil repeats:YES];

Où vos méthodes sont:

- (void) myMethod1:(NSTimer*)theTimer
{
  // Faire quelque chose
}

- (void) myMethod2:(NSTimer*)theTimer
{
  // Faire quelque chose de différent
}

Vous voulez enregistrer et conserver les références à la fois de timer1 et timer2, afin de pouvoir arrêter les timers dans dealloc ([timer1 invalidate]).

0voto

uliwitness Points 2085

Note courte: En général, il est de mauvais style d'avoir des déclarations "si" qui basculent sur un objet. Nous le faisons tous occasionnellement pour obtenir cette deuxième liste sans avoir besoin d'un nouveau contrôleur, mais basculer est ce que font les appels de méthode en interne, donc idéalement vous devriez laisser le ObjC s'occuper de faire ce qu'il faut. Plusieurs options:

-(void)   tableViewSelectionDidChange: (NSTableView*)theView
{
    SEL theAction = NSSelectorFromString( [NSString stringWithFormat: @"tableView%@SelectionDidChange:", [theView autosaveName]] );
    [self performSelector: theAction withObject: theView];
}

-(void) tableViewUKSourceListSelectionDidChange: (NSTableView*)theView
{
    // Choses spécifiques à la table UKSourceList ici.
}

-(void) tableViewUKUsersListSelectionDidChange: (NSTableView*)theView
{
    // Choses spécifiques à la table UKUsersList ici.
}

Cela fonctionne mieux lorsque vous avez une étiquette de chaîne non localisée, comme le nom de sauvegarde automatique, mais vous pouvez aussi utiliser la balise, bien que cela rende le code moins lisible (lequel est "table 1"?). Parfois, il est préférable d'écrire simplement une sous-classe qui a une chaîne spéciale à cet effet, ou même des méthodes où vous pouvez spécifier des noms de sélecteur pour transférer les méthodes du délégué.

La suggestion de Caleb est également bonne, elle est également appelée "cible/action" au cas où vous souhaiteriez faire une recherche dessus. J'ai plusieurs classes (Mac) qui ont une "action" régulière pour les clics, une "doubleAction" pour les doubles clics, etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X