2012-10-01 18 views
6

En mi aplicación tengo una UIViewController que utiliza una gran cantidad de UIAlertView pedir cosas para el usuario.Crear clases dinámicas personalizadas en Objective-C

porque necesito la respuesta de cada UIAlertView he hecho mi controlador de un delegado de UIAlertViewDelegate, esto funciona bien, pero después de 7 UIAlertView 's `m tratando de encontrar una mejor manera de utilizar los delegados.

en Java Sé que puedo crear clases en línea para un solo propósito, como en esta pregunta: Java - inline class definition

Lo que quiero saber es: ¿Hay una manera de crear una clase para ser delegado de forma dinámica? para lograr algo como esto

id<UIAlertViewDelegate> myCustomClass = @class { 
    my class code goes here 
} 

UIAlertView* alertView; 
alertView = [[UIAlertView alloc] initWithTitle:@"Title" 
             message:@"Message" 
             delegate:myCustomClass 
          cancelButtonTitle:@"No" 
          otherButtonTitles:@"OK", @"Sure", @"Maybe", nil] ];  
[alertView show]; 
+0

'@ class' tiene un significado totalmente diferente en Obj-C que lo que estás pensando. Declara una clase de 'reenvío' de tipo, FYI. –

+1

el punto de utilizar '' @ class'' es sólo para mostrar algo similar, para ayudar a explicar a nadie lo que estoy pensando. solo eso –

Respuesta

14

No - no hay 'clases en línea' en Objective-C. Dicho esto, puede crear objetos personalizados en tiempo de ejecución con objetivo-c, que es un poco más complicado, pero estaría dispuesto a compartir algún código para hacer lo que está diciendo.

Aquí es un ejemplo de que:

NSObject + Subclass.h

#import <objc/runtime.h> 

typedef struct selBlockPair { SEL aSEL; id (^__unsafe_unretained aBlock)(id, ...); } selBlockPair; 
#define NIL_PAIR ((struct selBlockPair) { 0, 0 }) 
#define PAIR_LIST (struct selBlockPair []) 
#define BLOCK_CAST (id (^)(id, ...)) 

@interface NSObject (subclass) 

+(Class) newSubclassNamed:(NSString *) name 
      protocols:(Protocol **) protos 
       impls:(selBlockPair *) impls; 

@end 

NSObject + Subclass.m

@implementation NSObject (subclass) 

+(Class) newSubclassNamed:(NSString *)name 
      protocols:(Protocol **)protos 
       impls:(selBlockPair *)impls 
{ 
    if (name == nil) 
    { 
     // basically create a random name 
     name = [NSString stringWithFormat:@"%s_%i_%i", class_getName(self), arc4random(), arc4random()]; 
    } 

    // allocated a new class as a subclass of self (so I could use this on a NSArray if I wanted) 
    Class newClass = objc_allocateClassPair(self, [name UTF8String], 0); 

    // add all of the protocols untill we hit null 
    while (protos && *protos != NULL) 
    { 
     class_addProtocol(newClass, *protos); 
     protos++; 
    } 

    // add all the impls till we hit null 
    while (impls && impls->aSEL) 
    { 
     class_addMethod(newClass, impls->aSEL, imp_implementationWithBlock(impls->aBlock), "@@:*"); 
     impls++; 
    } 

    // register our class pair 
    objc_registerClassPair(newClass); 

    return newClass; 
} 

@end 

Ejemplo de Uso:

int main() 
{ 
    @autoreleasepool { 
     __strong Class newClass = [NSString newSubclassNamed:@"MyCustomString" protocols:NULL impls: PAIR_LIST { 
      @selector(description), 
      BLOCK_CAST ^id (id self) { 
       return @"testing"; 
      }, 
      NIL_PAIR 
     }]; 

     NSString *someString = [newClass new]; 
     NSLog(@"%@", someString); 
    } 
} 

Salida:

 
2012-10-01 10:07:33.609 TestProj[54428:303] testing 
+0

Su respuesta respondió todas mis preguntas sobre las clases en línea y abrió otra serie de preguntas sobre su código. Gracias de verdad ahora estoy tratando de entender este código que publicaste. gracias de nuevo –

+0

@NicosKaralis no hay problema, si tiene alguna comprensión problemas, no tenga miedo de preguntar! –

+0

¡Brillante! Una pregunta rápida, ¿hay alguna manera fácil de llamar '[super description]' en la impl personalizada? – ccwasden

3

Este tipo de Java clase interna anónima no es algo que se apoya en Objective-C. Si desea responder a los delegados de forma individual, la buena forma es experimentar con bloques.

Desafortunadamente, Apple no ha añadido bloques en UIAlertViews, pero se les puede aplicar a sí mismo. Muchas personas lo han hecho en línea. Eche un vistazo aquí: http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ o https://github.com/MugunthKumar/UIKitCategoryAdditions.

La idea básica es que se puede crear una subclase (o una categoría si el uso de objetos asociados), que va a ser su propio delegado y contar su propia delegado para llamar a un bloque que se pasa en

+0

Tu respuesta también me ayudó mucho, tanques –

Cuestiones relacionadas