2012-02-29 10 views
5

Tengo algunos UIPopoverViewControllers que envían mensajes para delegar UIViewControllers para pasar eventos de IU. En lugar de escribir un método separado para cada evento, tengo un método en el delegado con una instrucción switch que determina cómo manejar el evento en función de una constante pasada (ejemplo a continuación).cómo compartir constantes (enumeraciones) entre clases?

Este es probablemente un diseño pobre, pero es lo que se me ocurrió. He visto this pregunta sobre enumeraciones o clases estáticas pero no entendí las respuestas.

Entonces, ¿qué es lo que estoy haciendo MALO y hay una manera en que puedo definir las enumeraciones en un solo lugar para que no tenga que mantener varios bits de código que puedan perderse fácilmente?

EDITAR bien, escarbar un poco más (+ herehere) Veo que podría estar en el camino correcto. Así que supongo que necesito saber qué y dónde está un archivo implementation en iOS.

enum { 
kSetPlaybackType = 0, 
kSetAllNotesOn, 
kSetAllNotesOff, 
kSetVelocity, 
kSetDuration 
}; 

- (void)barPropertyAction:(int)action withParam:(NSNumber *)param 
{ 
switch (action) { 
    case kSetPlaybackType: 
     playbackType = [param intValue]; 
     if (playbackType == kPalindrome){ 
      palindromeDirection = kPalindromeUp; 
     } 
     break; 

    case kSetAllNotesOn: 
     for (BarNote* note in self.barNoteArray) { 
      note.noteOn = YES; 
     } 
     [self.bar updateWindows]; 
     break; 

    case kSetAllNotesOff: 
     for (BarNote* note in self.barNoteArray) { 
      note.noteOn = NO; 
     } 
     [self.bar updateWindows]; 
     break; 

    case kSetVelocity: 
     for (BarNote* note in self.barNoteArray) { 
      note.velocity = [param intValue]; 
     } 
     break; 

    case kSetDuration: 
     for (BarNote* note in self.barNoteArray) { 
      note.duration = [param floatValue]; 
     } 
     break; 

    default: 
     break; 
} 
} 

Respuesta

14

No voy a decir que su enfoque es que es malo, pero tiene un ligero toque a él, del embrión a partir de un método de "dios" - que es un método que trata de hacer todo. Sin embargo, por la cantidad de opciones que tiene en el código, diría que está perfectamente bien.

Pero compartir la enumeración es muy fácil. Solo colóquelos en su propio archivo .h e impórtelos donde sea necesario. Puede incluir un archivo .h como uno de los tipos de archivo en la sección "C & C++".

La pregunta a la que se refirió estaba basada en C#, y una cosa que hicieron en ese lenguaje fue diseñar el equivalente de archivos .h, y simplemente usar declaraciones "using" para ubicar los símbolos correctos. En Objective-C (como en C y C++) tienes que hacer un poco más de trabajo manual para lograr lo mismo.

Por cierto, me gustaría vestir la enumeración hasta un poco más como:

typedef enum { 
    kSetPlaybackType = 0, 
    kSetAllNotesOn, 
    kSetAllNotesOff, 
    kSetVelocity, 
    kSetDuration 
} SetEnumType; 

Al declarar la enumeración en un typedef, se obtiene la capacidad para declarar variables de ese tipo. Es decir, en lugar de:

int varName = kSetAllNotesOn; 

Se puede decir:

SetEnumType varName = kSetAllNotesOn; 

Esto da consejos adicionales para XCode cuando se presenta con opciones de autocompletar, y hace que sea semánticamente mejor leer como una persona, como saben que varName está destinado a contener una enumeración y no solo cualquier número antiguo.

El inconveniente es que es posible que necesite emitir varnum explícitamente entre el tipo de enumeración y el tipo int, dependiendo de lo que esté haciendo.

Sin embargo no estoy seguro de si se puede declarar su método de firma como

- (void)barPropertyAction:(SetEnumType)action withParam:(NSNumber *)param 

que supongo que debe ser capaz de (como creo que la enumeración está respaldado por un int).Pero si no se puede, entonces sería mejor hacer

- (void)barPropertyAction:(int)action withParam:(NSNumber *)param 
{ 
switch ((SetEnumType)action) { 
    case kSetPlaybackType: 
     playbackType = [param intValue]; 
+0

Además, una de las cosas que debe hacer es nombrar a la enumeración utilizando un 'typedef' y no usar' int' como un parámetro, cuando una se espera una enumeración especificada. – Sulthan

+0

@Sulthan Yo estaba haciendo eso, como usted comentó: D –

+0

Esto es genial, ¡gracias! He agregado typedef + constant name, y moví los enum defs a un archivo .h. Pude usar typedef en mi método sig. '- (void) barPropertyAction: (kBarProperty) acción conParam: (NSNumber *) param;' –

Cuestiones relacionadas