Problèmes Objective-C avec NSDictionary et NSURL
-
21-08-2019 - |
Question
Je suis nouveau à Objective-C et je n'ai aucune idée pourquoi ce code ne fonctionne pas:
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'erreur que je reçois est:
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'
Toute aide serait appréciée. Merci.
La solution
touche est ce que vous utilisez pour accéder à un objet dans le dictionnaire. Vous avez vos clés et objets inversés sur chaque ligne que vous appelez dans le code -[bookmarks setObject:... forKey...]
. Le problème se pose dans votre cas parce que vous essayez de traiter des objets NSURL comme des objets NSString - [bookmarks objectForKey:(NSString *)each]
- et le dictionnaire tente d'obtenir la longueur de la chaîne supposée en appelant -length
, qui existe pour NSString mais pas pour NSURL .
Si vous construisez toujours un dictionnaire avec les mêmes objets, envisagez d'utiliser un constructeur plus compact « varargs » pour NSDictionary
. (Notez que le dernier argument séparés par des virgules doit-être nul - voir la documentation correspondante ) Vous pouvez également utiliser -[NSDictionary dictionaryWithObjects:forKeys:]
avec deux NSArray, contenant les URL et les noms de signet. (Par ailleurs, la coulée chaînes littérales comme NSString*
pour créer un NSURL est complètement 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];
En outre, vous avez une erreur qui se cache qui n'a pas été encore mentionné: browser
est un NSEnumerator
, mais vous appelez valueForKey:
comme si elle était un bookmarks
, plutôt que sur -objectForKey:
. Cela va provoquer un accident similaire pour un sélecteur non reconnu aussi. (Même pour les objets du dictionnaire, vous devez appeler -valueForKey:
à la place, -keyEnumerator
est utilisé principalement pour / par
Autres conseils
Vous avez le intiialization dictionnaire de signets inversé:
[bookmarks setObject:@"Stanford University" forKey:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"]];
Devrait être:
[bookmarks setObject:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"] forKey:@"Stanford University"];
En outre, il y a un moyen plus simple de faire de l'énumération:
NSURL *url;
for ( NSString *each in [bookmarks allKeys] )
{
url = [browser objectForKey:(NSString *)each];
NSLog(@"%@", [url absoluteURL]);
}
Vous pouvez également énumérer [signets allvalues] pour obtenir l'objet URL directement au lieu d'obtenir les clés d'abord (bien que vous pouvez bien vouloir les clés pour une autre raison).
Je pense que vous faites référence à la mauvaise variable dans votre boucle while en essayant d'obtenir l'URL (et je pense que vous devriez utiliser le sélecteur pour obtenir objectForKey:
une valeur d'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);
}
Je travaille dans les mêmes classes en ligne et a constaté que aucune des réponses ci-dessus semblent travailler soit parce que NSEnumerator peut ne pas répondre à objectForKey ou parce que le type d'énumération n'est pas pris en charge (peut-être pas dans le SDK iPhone par rapport OSX je ne sais pas). Je l'ai eu à travailler comme un charme comme suit si ...
NSString *aKey;
NSEnumerator *keyEnumerator = [bookmarks keyEnumerator];
NSURL *url;
while (aKey = [keyEnumerator nextObject])
{
url = [bookmarks objectForKey:aKey];
NSLog(@"value: %@", [url absoluteURL]);
}