iOS: это хороший способ проверить, является ли объект словаря JSON строкой NSString? - PullRequest
0 голосов
/ 20 октября 2018

Я хочу проверить, является ли объект JSON строкой NSString, и, если это не так, назначить ему строку по умолчанию.Моя конечная цель - предотвратить сбои и присвоить свойствам правильное значение, несмотря ни на что.Это пример модели данных, которую я использую, где dict - это словарь JSON, который возвращает API.

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

Вот метод категории validateString, который я использую.

+ (NSString *)validateString:(NSString *)aString defaultString:(NSString *)defaultString {
    if ([aString isKindOfClass:[NSString class]]) {
        return aString;
    }
    return defaultString;
}

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Как упомянуто в других комментариях: если вы хотите предотвратить сбои, вам также необходимо проверить, является ли он nil, особенно если есть вероятность перенести ваш код в Swift в будущем.

ПростоЧтобы прояснить мое последнее предложение, строка ниже работает в Objective-C, даже если aString равен nil:

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

Это потому, что, как Objective-C был сделан, вызов функции наnil объект возвращает nil, поэтому if будет считаться false, а функция вернет defaultString.Да ... это, конечно, плохая идея, когда они создали Objetive-C, поскольку это приводит к большому количеству ошибок.Подробнее об этом поведении читайте ниже:

https://stackoverflow.com/a/2696909

В любом случае, хорошей практикой является также приведение объекта только после проверки его типа, поэтому я рекомендую адаптировать вашу функцию к этому:

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

Каждый объект, который реализует NSObject*, имеет isKindOfClass:NSDictionary* хранит только объекты, которые реализуют NSObject*), поэтому нам не нужно проверять, реагирует ли объект на него.Кроме того, даже если мы хотим, respondsToSelector: также является функцией NSObject*.

Тем не менее используемый вами метод все еще работает.Пересмотренная выше функция просто адаптирована для лучшей практики и позволяет избежать проблем в случае, если вам когда-нибудь понадобится перенести этот код на Swift (или любой другой язык) в будущем.

РЕДАКТИРОВАТЬ: обновленный код, основанный на предложении @ matt.

0 голосов
/ 20 октября 2018

Нет смысла, и это очень плохая практика, разыгрывать (NSString *)aString и затем спрашивать, действительно ли это строка NSString.

Кроме того, что, если это ноль?

Все, что вы знаете, когда выбираете из словаря, это то, что вы получаете id.Не предполагайте больше, чем это.

Я бы предложил написать очень просто: скажите, что вы имеете в виду, и скажите, что вы говорите.Это лучшая практика в Objective-C.В противном случае, динамическая типизация и «ноль трюки» могут привести к тонким ошибкам.В этом конкретном случае у вас могут не возникнуть никаких проблем, но вредные привычки - это вредные привычки, и лучше всего не дать им сформироваться в первую очередь.Я бы переписал так:

+ (NSString *) checkType:(nullable id)obj defaultString:(NSString *)def {
    if (obj == nil || ![obj isKindOfClass:[NSString class]]) {
        return def;
    }
    return obj;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...