Domanda

Sono nuovo a Objective-C e non ho indizio perché questo codice non funziona:

    NSMutableDictionary *bookmarks = [NSMutableDictionary dictionaryWithCapacity:(NSUInteger) 4];
[bookmarks setObject:@"Stanford University" forKey:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"]];
[bookmarks setObject:@"Apple" forKey:[NSURL URLWithString:(NSString *) @"http://www.apple.com"]];
[bookmarks setObject:@"Berkeley" forKey:[NSURL URLWithString:(NSString *) @"http://www.berkeley.edu"]];
[bookmarks setObject:@"CS193P" forKey:[NSURL URLWithString:(NSString *) @"http://cs193p.stanford.edu"]];

NSEnumerator *browser = [bookmarks keyEnumerator];
id each;
NSURL *url;
while ((each = [browser nextObject])) {
    url = [browser valueForKey:(NSString *)each];
    NSLog(@"%@", [url absoluteURL]);
}

L'errore che ottengo è:

2009-06-29 11:25:22.844 WhatATool[2102:10b] *** -[NSURL length]: unrecognized selector sent to instance 0x1072c0
2009-06-29 11:25:22.845 WhatATool[2102:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL length]: unrecognized selector sent to instance 0x1072c0'

Qualsiasi aiuto sarebbe apprezzato. Grazie.

È stato utile?

Soluzione

Un chiave è quello che si utilizza per accedere a una oggetto nel dizionario. Hai le chiavi e oggetti invertiti su ogni linea si chiama -[bookmarks setObject:... forKey...] nel codice. Il problema nel tuo caso nasce dal fatto che si sta cercando di trattare gli oggetti come oggetti NSURL NSString - [bookmarks objectForKey:(NSString *)each] - e il dizionario sta cercando di ottenere la lunghezza della stringa presunta chiamando -length, che esiste per NSString ma non per NSURL .

Se si sta costruendo sempre un dizionario con gli stessi oggetti, è possibile utilizzare una funzione di costruzione più compatta "varargs" per NSDictionary. (Si noti che l'ultimo argomento separato da virgole deve essere pari a zero - vedi la relativa documentazione ) È inoltre possibile utilizzare -[NSDictionary dictionaryWithObjects:forKeys:] con due oggetti NSArray, contenente gli URL e i nomi di segnalibro. (Per inciso, gettando stringhe letterali come NSString* per creare un NSURL è completamente inutile.)

NSDictionary *bookmarks = [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSURL URLWithString:@"http://www.stanford.edu"],
                           @"Stanford University",
                           [NSURL URLWithString:@"http://www.apple.com"],
                           @"Apple",
                           [NSURL URLWithString:@"http://www.berkeley.edu"],
                           @"Berkeley",
                           [NSURL URLWithString:@"http://cs193p.stanford.edu"],
                           @"CS193P",
                           nil];

Inoltre, si dispone di un errore in agguato che non è stato ancora citato: browser è un NSEnumerator, ma si sta chiamando valueForKey: come se fosse un bookmarks, piuttosto che su -objectForKey: . Ciò causerà un crash simile per un selettore non riconosciuto, anche. (Anche per gli oggetti del dizionario, si dovrebbe chiamare -valueForKey: invece, -keyEnumerator viene utilizzato per lo più per / da cacao Associazioni , e lo fa di lavoro extra non è necessario mi rendo conto che è confusa perché pensiamo in. termini di "coppie chiave-valore", ma non v'è ...)

Infine, è anche possibile semplificare il codice di enumerazione un po '. (A per-in loop su un <=> enumera le sue chiavi, proprio come farebbe <=>.)

Ecco come Io suggerirei di fare l'ultima parte:

NSURL *url
for (NSString *key in bookmarks) {
    url = [bookmarks objectForKey:key];
    NSLog(@"%@", [url absoluteURL]);
}

Altri suggerimenti

Hai l'intiialization dizionario preferiti invertito:

[bookmarks setObject:@"Stanford University" forKey:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"]];

Dovrebbe essere:

[bookmarks setObject:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"] forKey:@"Stanford University"];

Inoltre, non c'è un modo più semplice per fare l'enumerazione:

NSURL *url;
for ( NSString *each in [bookmarks allKeys] ) 
{
        url = [browser objectForKey:(NSString *)each];
        NSLog(@"%@", [url absoluteURL]);
}

Si potrebbe anche enumerare [segnalibri allValues] per ottenere l'oggetto URL direttamente invece di ottenere le chiavi prima (anche se ci si vorrà le chiavi per qualche altra ragione).

Penso che si stia riferendo alla variabile sbagliato nel vostro ciclo while quando si cerca di ottenere l'URL (e penso che si dovrebbe usare il objectForKey: di selezione per ottenere un valore di un NSDictionary, non valueForKey:):

NSEnumerator *browser = [bookmarks keyEnumerator];
id each;
NSURL *url;
while ((each = [browser nextObject])) {
    url = [bookmarks objectForKey:(NSString *)each]; // <-- bookmarks, not browser
    NSLog(@"URL = %@", url);
}

Sto lavorando attraverso le stesse lezioni on-line e ha scoperto che nessuna delle risposte di cui sopra sembra funzionare o perché NSEnumerator potrebbe non rispondere alle objectForKey o perché il particolare tipo di enumerazione non è supportato (forse non in iPhone SDK rispetto per OSX non so). Ho preso a lavorare come un fascino come segue se ...

NSString *aKey;
NSEnumerator *keyEnumerator = [bookmarks keyEnumerator];
NSURL *url;

while (aKey = [keyEnumerator nextObject])
{
    url = [bookmarks objectForKey:aKey];
    NSLog(@"value: %@", [url absoluteURL]);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top