2012-10-01 11 views
6

Nella mia applicazione ho un UIViewController che uso un sacco di UIAlertView per chiedere informazioni all'utente.Creare classi dinamiche personalizzate nell'obiettivo-

perché ho bisogno della risposta di ogni UIAlertView ho fatto il mio controller un delegato di UIAlertViewDelegate, questo funziona bene, ma dopo 7 UIAlertView 's `m cercando di trovare un modo migliore per utilizzare i delegati.

in Java So che posso creare classi in linea per un unico scopo, come in questa domanda: Java - inline class definition

Quello che voglio sapere è: C'è un modo per creare una classe di essere delegata in modo dinamico? per ottenere qualcosa di simile

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' ha un significato completamente diverso in Obj-C di quello che stai pensando. Dichiara una sorta di "classe di inoltro", FYI. –

+1

il punto di usare '' @ classe'' è solo per mostrare qualcosa di simile, per aiutarmi a spiegare a chiunque quello che sto pensando. solo quello –

risposta

14

No - non ci sono "classi in linea" in Objective-C. Detto questo, è possibile creare oggetti personalizzati in fase di esecuzione con l'obiettivo-c, che è un po 'più coinvolto, ma sarei disposto a condividere del codice per fare ciò che stai dicendo.

Ecco un esempio di quella:

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 

Esempio 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); 
    } 
} 

uscita:

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

La tua risposta ha risposto a tutte le mie domande sulle classi inline e ha aperto un altro gruppo di domande sul tuo codice. Grazie per davvero. ora sto cercando di capire questo codice che hai postato. grazie ancora –

+0

@NicosKaralis nessun problema, se avete problemi di comprensione, non abbiate paura di chiedere! –

+0

Brillante! Una domanda veloce, c'è un modo semplice per chiamare '[super description]' nell'impianto personalizzato? – ccwasden

3

Questo tipo di Java classe interna anonima non è qualcosa che è supportato in Objective-C. Se vuoi rispondere ai delegati individualmente, il mio buon metodo è sperimentare i blocchi.

Sfortunatamente, Apple non ha aggiunto blocchi in UIAlertViews, ma è possibile implementarli da soli. Un sacco di persone lo hanno fatto online. Dai un'occhiata qui: http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ o https://github.com/MugunthKumar/UIKitCategoryAdditions.

L'idea di base è che si può creare una sottoclasse (o una categoria se si utilizza oggetti associati), che sarà il suo delegato e raccontare la propria delegato di chiamare un blocco si passa

+0

Anche la tua risposta mi aiuta molto, carri armati –

Problemi correlati