-[NSNull lunghezza]: non riconosciuto selettore inviato a oggetti JSON

Sto sviluppando una versione di iOS 5.0+ app con l’ultima versione dell’SDK.

Ho un errore strano con questo codice:

- (NSMutableURLRequest*)setupRequestWithService:(NSString*)service andMethod:(NSString*)method
{
    NSString* url = [NSString stringWithFormat:@"%@%@.svc/%@", serverUrl, service, method];

    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];

    //Set authentication token.
    NSLog(@"???????????? %@", authenticationToken);
    if (authenticationToken == nil)
        NSLog(@"NULL AUTHTOKEN");
    if ([authenticationToken isEqual:[NSNull null]])
        NSLog(@"NSNULL AUTHTOKEN");
    if (request == nil)
        NSLog(@"NULL REQUEST");
    [request addValue:authenticationToken forHTTPHeaderField:REQUEST_HEADER_AUTH_TOKEN];

    return request;
}

Questo è il mio log:

???????????? <null>
NSNULL AUTHTOKEN
-[NSNull length]: unrecognized selector sent to instance 0x3b5a5090
    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x3b5a5090'

Sembra che authenticationToken è NULL. Ma non ho capito che, se authenticationToken è NULL perché non vedo NULL AUTHTOKEN sul registro.

Ottengo questo errore per la seconda volta ho eseguito questo metodo, la prima volta, non ottengo alcun errore. Questo è il mio log:

???????????? (null)
NULL AUTHTOKEN

:

NSString* authenticationToken;

Qualche consiglio?

Forse c’è un Memory Leak da qualche parte…

è NSNull, non nullo. developer.apple.com/library/ios/#documentation/cocoa/reference/…
È necessario verificare con se([NSNull null]== authenticationToken){NSLog(@”NULL AUTHTOKEN”);}
Sì, probabilmente è goth authenticationToken da JSON, e aveva un valore null per il valore, quindi un NSNull oggetto è ciò che è dato per voi. Si può effettivamente fare authenticationToken == [NSNull null] per il test di questo, dal momento che c’è sempre, e solo, esattamente un NSNull oggetto in app.
Se si aggiungi il tuo commento come risposta, posso accettare.

OriginaleL’autore VansFannel | 2013-05-17

4 Replies
  1. 79

    La mia soluzione a questo esasperante uso di NSNull da JSON interpreti è quello di creare una categoria NSNull, dove posso definire integerValue, floatValue, lunghezza, ecc – return 0 per tutti. Ogni volta che si ottiene un altro crash aggiungere una nuova categoria. Penso che ho avuto 6 o 7 anni quando ho avuto questo problema.

    Il problema NON si fa questo è che si deve guardare per il valore NULL ovunque nel vostro convertiti in oggetti – una valle di lacrime, a mio parere.

    EDIT: il codice che sto usando, il tutto in un NSNull+JSON.m file:

    @interface NSNull (JSON)
    @end
    
    @implementation NSNull (JSON)
    
    - (NSUInteger)length { return 0; }
    
    - (NSInteger)integerValue { return 0; };
    
    - (float)floatValue { return 0; };
    
    - (NSString *)description { return @"0(NSNull)"; }
    
    - (NSArray *)componentsSeparatedByString:(NSString *)separator { return @[]; }
    
    - (id)objectForKey:(id)key { return nil; }
    
    - (BOOL)boolValue { return NO; }
    
    @end

    EDIT2: Ora in Swift 3:

    extension NSNull {
       func length() -> Int { return 0 }
    
       func integerValue() -> Int { return 0 }
    
       func floatValue() -> Float { return 0 };
    
       open override var description: String { return "0(NSNull)" }
    
       func componentsSeparatedByString(separator: String) -> [AnyObject] { return [AnyObject]() }
    
       func objectForKey(key: AnyObject) -> AnyObject? { return nil }
    
       func boolValue() -> Bool { return false }
    }
    Voi, signore, sono un genio.
    Capolavoro soluzione. Wow 🙂
    Grazie per l’aggiornamento del codice. Sarebbe sicuramente aiutare un sacco di popoli.
    Questo è stato il primo in MODO da rispondere a farmi ridere a voce alta (“Ogni volta che si ottiene un nuovo incidente…”)
    Scusa, intendevo dire che in un totalmente gratuito/modo impressionante. Come wow, non avrei mai pensato che e ‘ fresco/eccentrico.

    OriginaleL’autore David H

  2. 6

    Il messaggio di errore è abbastanza chiaro. NSNull e nil sono cose diverse:

    The NSNull class defines a singleton object used to represent null values in 
    collection objects (which dont allow nil values).

    Se si desidera controllare se authenticationToken è NSNull provare: [authenticationToken isEqual: [NSNull null]]

    Grazie per la tua risposta, ma non aiuta. Voglio solo sapere cosa succede. Ho un NSString e poi si passa a NSNull.
    Allora si dovrebbe fare la domanda.

    OriginaleL’autore Mar0ux

  3. 2

    In linea con David H la risposta, come su di una categoria NSNull che utilizza solo ObjC dell’inoltro del messaggio di “non fare nulla”, per emulare il comportamento del runtime durante l’invio di messaggi di nil?

    Come questo:

    @interface NSNull (ForwardInvocation)
    
    @end
    
    @implementation NSNull (ForwardInvocation)
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
        return [NSNull methodSignatureForSelector:@selector(description)];
    }
    
    - (void)forwardInvocation:(NSInvocation *)anInvocation {
        //do nothing; prevent 'unrecognized selector' crashes
    }
    
    @end

    Il [NSNull methodSignatureForSelector:@selector(description)]; sfrutta il fatto che NSNull eredita da NSObject, che prevede la description metodo. Questo soddisfa il meccanismo di inoltro requisito per l’attuazione -methodSignatureForSelector:.

    Credo che questo non funziona. Quello che la mia soluzione non è tornare un digitato “nulla”, in modo che il destinatario può utilizzare il valore allo stesso modo sarebbe una “vera” risposta. Nota in un caso viene restituito un array vuoto. Inoltre, si ottiene la descrizione unica, così si può vedere i valori null in fase di debug.
    Non funziona nel mio caso, e ci si sente come una soluzione più generica. Grazie!
    Grazie!
    Sei corretto, la mia soluzione è più orientata verso ignorando objc i messaggi inviati a NSNull, per evitare l’ignoto selettore di errore. Ma per fornire i valori di default per il parsing JSON, la tua soluzione è più adatta allo scopo.

    OriginaleL’autore Eric Baker

  4. 0

    Il problema nasce perché il metodo di restituzione di un NSNull oggetto.
    Non è possibile controllare [authenticationToken isEqual:[NSNull null]]) perché [NSNull null] dare un’istanza di un oggetto. Quindi è diverso dall’oggetto stesso.
    Se si desidera controllare se si è ricevuto un NSNull oggetto, è necessario verificare come questo: [authenticationToken isKindOfClass:[NSNull class]] invece.

    OriginaleL’autore Daniel C.

Lascia un commento