iOS: esta é uma boa maneira de verificar se o objeto do dicionário JSON é um NSString?

votos
0

Quero verificar se um objeto JSON é um NSString e se não é, atribuir a ele uma seqüência padrão. Meu objetivo final é para evitar falhas e atribuir as propriedades de um valor adequado, não importa o quê. Este é um exemplo de um modelo de dados que estou usando, onde dict é o dicionário JSON a API retorna.

 Data *data = [[self alloc] init];
 data.name =  [NSString validateString:dict[@name] defaultString:@];
 data.status = [NSString validateString:dict[@status] defaultString:@OPEN];

Aqui está o método categoria validateStringque estou usando.

+ (NSString *)validateString:(NSString *)aString defaultString:(NSString *)defaultString {
    if ([aString isKindOfClass:[NSString class]]) {
        return aString;
    }
    return defaultString;
}
Publicado 20/10/2018 em 13:58
fonte usuário
Em outras línguas...                            


2 respostas

votos
2

Não faz sentido, e é muito má prática, para lançar (NSString *)aStringe, em seguida, perguntar se este é de fato um NSString.

Além disso, o que se é nulo?

Tudo o que você sabe quando você buscar de um dicionário é que você começa um id. Não assuma mais do que isso.

Eu sugeriria escrevendo muito claramente: dizer o que você quer dizer e dizer o que disse. Essa é a melhor prática em Objective-C. Caso contrário, tipagem dinâmica e "truques nulo" pode levá-lo em erros sutis. Você pode não ter nenhum problema neste caso em particular, mas os maus hábitos são maus hábitos, e é melhor não deixá-los formar em primeiro lugar. Eu reescrever como esta:

+ (NSString *) checkType:(nullable id)obj defaultString:(NSString *)def {
    if (obj == nil || ![obj isKindOfClass:[NSString class]]) {
        return def;
    }
    return obj;
}
Respondeu 20/10/2018 em 14:55
fonte usuário

votos
0

Como mencionado em outros comentários: se você quer evitar acidentes, você também precisa verificar se é nil, especialmente se houver uma chance de portar seu código para Swift no futuro.

Só para esclarecer a minha última frase, a linha a seguir funciona em Objective-C, mesmo se aStringé nil:

if ([aString isKindOfClass:[NSString class]]) {

Isso porque, no caminho Objective-C foi feita, chamar uma função em um nilobjeto retorna nil, assim o ifserá considerado false, e a função retornará defaultString. Sim ... isso é certamente uma má idéia quando criaram Objetivo-C, uma vez que este conduz a muitos erros. Mais detalhes sobre esse comportamento abaixo:

https://stackoverflow.com/a/2696909

De qualquer forma, também é uma boa prática apenas converter um objeto depois de verificar seu tipo, então eu recomendaria adaptando a função para isso:

+ (NSString *)validateString:(id)obj defaultString:(NSString *)defaultString {
    if (obj != nil && [obj isKindOfClass:[NSString class]]) {
        return (NSString*)obj;
    }
    return defaultString;
}

Cada objeto que implementa NSObject*tem isKindOfClass:(e NSDictionary*só armazena objetos que implementam NSObject*), de modo que não precisa verificar se o objeto responde a ele. Além disso, mesmo se quiséssemos, respondsToSelector:também é uma NSObject*função.

Ainda assim, o método que você está usando ainda funciona. A função revisto acima é apenas adaptado para melhores práticas e para evitar problemas no caso de você precisar porto este código Swift (ou qualquer outra língua) no futuro.

EDIT: código atualizado com base na sugestão de @ mate.

Respondeu 20/10/2018 em 15:19
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more