2013-05-17 8 views
2

У меня есть строка из JSON, которая иногда выглядит так: «2, 18, 27, 29» называется mayString. Другие времена эта строка будет просто @ «2» (Один номер и нет разделения запятой)RangeOfString crash on not found result iOS

Я хочу, чтобы проверить, если строка содержит запятую, используя код ниже:

NSRange range = [mayString rangeOfString:@","]; 
     if (range.location != NSNotFound) { 
      NSLog (@"Substring found at: %d", range.location); 
     } 

     else{ 

      NSLog (@"Substring not found"); 
     } 

Это прекрасно работает, когда строка содержит разделение запятой, но сбой, когда нет запятой, я бы ожидал, что журнал скажет "Substring not found"? Но я получаю [__NSCFNumber rangeOfString:]: unrecognized selector sent to instance 0x1d533500

ответ

3

попробовать ниже код ..., как Marcin прав ...

NSRange range = [[NSString stringWithFormat:@"%@",mayString] rangeOfString:@","]; 
     if (range.location != NSNotFound) { 
      NSLog (@"Substring found at: %d", range.location); 
     } 

     else{ 

      NSLog (@"Substring not found"); 
     } 
+0

Да, это сработало, это немного мусор, который JSON сделает, я бы никогда не подумал, что это так. Я ожидал бы, если я объявлю и хочу строку, я получаю строку, а не число ... но я всегда учусь. Cheers –

+0

.... приветствия ... также проверяют ответ @ dasblinkenlight..это умный подход ... – BhushanVU

5

Похоже, что ваша «строка» на самом деле является экземпляром NSNumber.

+0

своей Дефо строки (неатомическая, сильная) NSString * mayString; –

+0

Ваша собственность может быть определена как NSString, но когда вы конвертируете данные JSON в объекты Foundation, строка без запятых интерпретируется как число. –

+0

+1 хороший. нужно больше объяснений. –

4

Поскольку JSON нетипизирован, парсер пытается выяснить, что внутри строки. Когда строка выглядит как номер, скажем, @"2", JSON возвращает вам объект NSNumber, а не NSString. Вы можете назначить его переменной NSString *, а компилятор Objective C не будет жаловаться, но значение внутри останется NSNumber.

Вот как вы можете это исправить:

id myObject = ... // Instead of MSString *myString 

if ([myObject isKindOfClass:[NSNumber class]]) { 
     NSLog (@"Object is not a string"); 
} else if ([myObject isKindOfClass:[NSString class]]) { 
    NSRange range = [mayString rangeOfString:@","]; 
    if (range.location != NSNotFound) { 
     NSLog (@"Substring found at: %d", range.location); 
    } else{ 
     NSLog (@"Substring not found"); 
    } 
} 

Вы также можете заставить его в строку, как это:

myString = [myString description]; // Not recommended 

Даже если myString был NSNumber перед тем выше назначение, он будет быть NSString после него, независимо от его начального типа. Однако сохранение исходного типа обычно является лучшим подходом.

+0

Наверняка нет, когда его объявлено как строка и выглядит как строка, другая - успешная находка, не будет найдена другой раз нет? –

+0

@AlexMcPherson То, что оно объявлено, не представляет интереса для компилятора. Объект C не является строго типизированным языком, вы можете присвоить 'NSNumber'' NSString', и компилятору все равно. Парсер JSON вернет строку, когда данные не будут выглядеть как число. – dasblinkenlight

+0

большое спасибо за объяснение, что круто! Я тоже поддержал тебя. –

1

Если значение в формате JSON имеет только один номер, NSJSONSerializer всегда преобразовав его в NSNumber. Итак, ваш NSString фактически NSNumber. Вы можете проверить это с isKindOfClass:

if([mayString isKindOfClass:[NSNumber class]) { 
    // do something 
} 

EDIT: извините дубликат ответа, мое умение писать не так хорошо

+0

да, ребята, вы правы, я не знал этого спасибо! –