Domanda

avendo alcuni problemi con la ... in ObjectiveC.

Sono fondamentalmente avvolgendo un metodo e vogliono accettare un nil lista terminata e direttamente passare lo stesso elenco per il metodo che sto avvolgendo.

Ecco quello che ho, ma provoca un incidente EXC_BAD_ACCESS. Ispezione delle vars locali, appare quando otherButtonTitles è semplicemente un NSString quando viene passato con otherButtonTitles:@"Foo", nil]

+ (void)showWithTitle:(NSString *)title
              message:(NSString *)message
             delegate:(id)delegate
    cancelButtonTitle:(NSString *)cancelButtonTitle
    otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title
                                                     message:message
                                                    delegate:delegate
                                           cancelButtonTitle:cancelButtonTitle
                                           otherButtonTitles:otherButtonTitles] autorelease];
    [alert show];
}

Come faccio semplicemente sifone dalla discussione in arrivo per l'argomento in uscita, mantenendo la stessa identica nil lista terminato?

È stato utile?

Soluzione

Non si può fare questo, almeno non nel modo in cui hai intenzione di farlo. Che cosa si vuole fare (passare sugli argomenti variabili) richiede avere un inizializzatore su UIAlertView che accetta un va_list. Non c'è una sola. Tuttavia, è possibile utilizzare il metodo addButtonWithTitle::

+ (void)showWithTitle:(NSString *)title
              message:(NSString *)message
             delegate:(id)delegate
    cancelButtonTitle:(NSString *)cancelButtonTitle
    otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title
                                                     message:message
                                                    delegate:delegate
                                           cancelButtonTitle:cancelButtonTitle
                                           otherButtonTitles:nil] autorelease];
    if (otherButtonTitles != nil) {
      [alert addButtonWithTitle:otherButtonTitles];
      va_list args;
      va_start(args, otherButtonTitles);
      NSString * title = nil;
      while(title = va_arg(args,NSString*)) {
          [alert addButtonWithTitle:title];
      }
      va_end(args);
    }

    [alert show];
}

Questa è, ovviamente, molto problema specifico. La vera risposta è "non è possibile passare in modo implicito in un elenco di argomenti variabili a un metodo / funzione che non dispongono di un parametro va_list". È quindi necessario trovare un modo per aggirare il problema. Nell'esempio hai dato, si voleva fare un alertView con i titoli avete passato. Fortunatamente per voi, la classe UIAlertView ha un metodo che è possibile chiamare per iterativamente aggiungere pulsanti, e quindi ottenere lo stesso effetto complessivo. Se non avesse questo metodo, devi essere fuori di fortuna.

L'altra opzione davvero disordinato potrebbe essere quella di rendere una macro variadic. Una macro variadic assomiglia a questo:

#define SHOW_ALERT(title,msg,del,cancel,other,...) { \
  UIAlertView *_alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:del cancelButtonTitle:cancel otherButtonTitles:other, ##__VA_ARGS__] autorelease]; \
  [_alert show]; \
}

Tuttavia, anche con l'approccio macro variadic, saresti ancora bisogno di una macro personalizzata per ogni volta che si voleva fare questo. Non è una solida alternativa.

Altri suggerimenti

Che ne dite di costruire un oggetto NSInvocation? Dal momento che gli argomenti devono essere passati per puntatore, si potrebbe passare il puntatore alla lista terminata da zero.

Si potrebbe anche scorrere i parametri utilizzando marg_list() e costruire un elenco terminata da zero da soli.

Questi sono solo semplici suggerimenti; Non li ho provato.

Questo è specifico per caso UIAlertView-wrapping del PO, e testato solo su iOS7: Sembra che una volta UIAlertView è stato inizializzato con otherButtons:nil, e poi ha messo il suo stile di UIAlertViewStylePlainTextInput esso non chiama alertViewShouldEnableFirstOtherButton: dei suoi delegati per la convalida ingresso. Non sono sicuro se questo è un bug o un comportamento previsto ma è rotto il principio del minimo stupore. Questo è riproducibile con la seguente (io presumo alertViewShouldEnableFirstOtherButton: del delegato è implementato):

UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Title" 
                                             message:@"message" 
                                            delegate:self         
                                   cancelButtonTitle:@"Cancel" 
                                   otherButtonTitles:nil];
[av setAlertViewStyle:UIAlertViewStylePlainTextInput];
[av addButtonWithTitle:@"OK"];
[av show];

La soluzione, poiché UIAlertView accetta tranquillamente otherButtons:nil, è di inizializzare UIAlertView con otherButtonTitles (che può essere zero), e iterare gli argomenti variadic, come sopra:

+ (void)showWithTitle:(NSString *)title
              message:(NSString *)message
             delegate:(id)delegate
    cancelButtonTitle:(NSString *)cancelButtonTitle
    otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title
                                                     message:message
                                                    delegate:delegate
                                           cancelButtonTitle:cancelButtonTitle
                                           otherButtonTitles:otherButtonTitles] autorelease];

    // add your [alert setAlertViewStyle:UIAlertViewStylePlainTextInput] etc. as required here

    if (otherButtonTitles != nil) {
        va_list args;
        va_start(args, otherButtonTitles);
        NSString * title = nil;
        while(title = va_arg(args,NSString*)) {
            [alert addButtonWithTitle:title];
        }
        va_end(args);
    }

    [alert show];
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top