Pergunta

Eu sou novo para Objective-C e eu não tenho idéia por que este código não está funcionando:

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

O erro que eu recebo é:

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'

Qualquer ajuda seria apreciada. Obrigado.

Foi útil?

Solução

A tecla é o que você usa para acessar um objeto no dicionário. Você tem suas chaves e objetos revertida em cada linha que você chama -[bookmarks setObject:... forKey...] no código. O problema no seu caso surge porque você está tentando tratar NSURL objetos como objetos NSString - [bookmarks objectForKey:(NSString *)each] -. E o dicionário está tentando obter o comprimento da corda suposto chamando -length, que existe para NSString mas não para NSURL

Se você está sempre construindo um dicionário com os mesmos objetos, considerar o uso de uma forma mais compacta "varargs" construtor para NSDictionary. (Note-se que o último argumento separados por vírgula deve ser nulo - veja documentação relacionada) Você também pode usar -[NSDictionary dictionaryWithObjects:forKeys:] com dois NSArray objetos, contendo os URLs e o marcador nomes. (Aliás, lançando strings literais como NSString* para criar um NSURL é completamente desnecessário.)

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];

Além disso, você tem um erro de espreita que não tenha sido mencionado ainda: browser é um NSEnumerator, mas você está chamando valueForKey: como se fosse um NSDictionary , em vez de bookmarks . Isso vai causar um acidente semelhante para um selector não reconhecido também. (Mesmo para objetos do dicionário, você deve chamar -objectForKey: vez; -valueForKey: é usado principalmente para / por Cacau Bindings , e faz o trabalho extra que você não precisa. Sei que é confuso, uma vez que pensar em termos de" chave noreferrer nofollow pares de valor", mas não é ...)

Finalmente, você também pode simplificar o código de enumeração um pouco. (A para-in circuito em um NSDictionary enumera suas chaves assim como -keyEnumerator faria.)

Aqui está como eu sugiro fazer a última parte:

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

Outras dicas

Você tem os marcadores intiialization dicionário invertida:

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

Deve ser:

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

Além disso, há uma maneira simples de fazer a enumeração:

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

Você também pode enumerar através [marcadores allvalues] para obter o objeto URL diretamente em vez de receber as chaves em primeiro lugar (embora você pode muito bem querer as chaves para alguma outra razão).

Eu acho que você está se referindo a variável de errado em seu loop while ao tentar obter a URL (e eu acho que você deve estar usando o seletor objectForKey: para obter um valor de um NSDictionary, não valueForKey:):

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

Eu estou trabalhando pelas mesmas aulas on-line e descobriu que nenhuma das respostas acima parece que quer trabalhar porque NSEnumerator pode não responder a objectForKey ou porque o tipo de enumeração não é suportada (talvez não no iPhone SDK, em comparação a OSX eu não sei). Eu tenho que trabalhar como um encanto como segue embora ...

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

while (aKey = [keyEnumerator nextObject])
{
    url = [bookmarks objectForKey:aKey];
    NSLog(@"value: %@", [url absoluteURL]);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top