2010-11-03 112 views
1

我有一個代碼,我正在從iOS 4移植到iOS 3.2的iPad上的演示項目。我有這樣的代碼:NSNumberFormatter iOS 3.2錯誤?

+(int) parseInt:(NSString *)str 
{ 
    NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 
    [nf setAllowsFloats:NO]; 
    [nf setMaximum:[NSNumber numberWithInt:INT_MAX]]; 
    [nf setMinimum:[NSNumber numberWithInt:INT_MIN]]; 

    @try { 
     NSNumber *num = [nf numberFromString:str]; 
     if (!num) 
      @throw [DataParseException exceptionWithDescription:@"the data is not in the correct format."]; 

     return [num intValue]; 
    } 
    @finally { 
     [nf release]; 
    } 
} 

這工作spendid在iOS 4,拋出異常,當一個字符串(如日期,這我有問題): 1/1/2010

出於某種原因,NUM ISN 'nil,它的值爲1,而在iOS 4上,它是沒有預期的。我最初使用的是NSScanner,因爲它比NSNumberFormatter更容易使用,但我遇到了同樣的問題,它不解析整個字符串,只是字符串中的第一個數字。

有什麼我可以做的,以解決這個問題,或者我必須手動創建一個int分析器。我寧願不使用基於C語言的方法,但如果必須的話,我會。

編輯:我已經更新了我的代碼如下:

+(int) parseInt:(NSString *)str 
{ 
    NSNumberFormatter *nf = [[NSNumberFormatter alloc] init]; 
    [nf setAllowsFloats:NO]; 
    [nf setMaximum:[NSNumber numberWithInt:INT_MAX]]; 
    [nf setMinimum:[NSNumber numberWithInt:INT_MIN]]; 

    @try { 
     IF_IOS4_OR_GREATER 
     (
       NSNumber *num = [nf numberFromString:str]; 
      if (!num) 
       @throw [DataParseException exceptionWithDescription:@"the data is not in the correct format."]; 

      return [num intValue]; 
     ) 
     else { 
      NSNumber *num = nil; 
      NSRange range = NSMakeRange(0, str.length); 
      NSError *err = nil; 
      [nf getObjectValue:&num forString:str range:&range error:&err]; 
      if (err) 
       @throw [DataParseException exceptionWithDescription:[err description]]; 
      if (range.length != [str length]) 
       @throw [DataParseException exceptionWithDescription:@"Not all of the number is a string!"]; 
      if (!num) 
       @throw [DataParseException exceptionWithDescription:@"the data is not in the correct format."]; 

      return [num intValue]; 
     } 
    } 
    @finally { 
     [nf release]; 
    } 
} 

而且我得到一個EXC_BAD_ACCESS信號,當我嘗試解析字符串1/1/2001。有任何想法嗎? (iOS的4或更大這裏定義:http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html

我有一個新的錯誤:當我解析的數目,它是不準確的(精確如它具有使用用於浮相同的代碼,當多個小數點)了......我怎麼能解決這個問題? (我可能只是使用@Joshpaul的答案...)

+0

你真的不應該爲此使用例外。 obj-c中的例外是爲了表示程序員錯誤。數據錯誤,比如這個,應該使用基於NSError *的API。 – 2010-11-04 09:18:03

+0

對不起,我的老闆和我在代碼中運行'nils'時出現問題... – 2010-11-04 11:04:03

+0

@Kevin Ballard:由於任何int都是有效的,所以沒有辦法指示錯誤值。 – JeremyP 2010-11-04 11:28:46

回答

1

那麼基本的[str intValue]不起作用?也不,[scanner scanInt:&int]

怎麼樣使用NSCharacterSet,即:

NSString *test = [str stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]]; 
if ([test length]) @throw ...; 
return [str intValue]; 
+0

一個有趣的解決方案....我不知道這對我是否實用..我會嘗試@JeremyP寫的東西,然後再看看你的答案 – 2010-11-04 10:47:30

4

我找不到任何具體到iOS但data formatting guide有這個有趣的段落:

Note: Prior to Mac OS v10.6, the implementation of getObjectValue:forString:errorDescription: would return YES and an object value even if only part of the string could be parsed. This is problematic because you cannot be sure what portion of the string was parsed. For applications linked on or after Mac OS v10.6, this method instead returns an error if part of the string cannot be parsed. You can use getObjectValue:forString:range:error: to get the old behavior; this method returns the range of the substring that was successfully parsed.

我也不會,如果在所有驚訝根據上述方法實現了numberFromString:,iOS 3.2 NSNumberFormatter基於10.5,而iOS 4的版本爲10.6。

只是我的猜測。

如果您在iOS 3.2上通過1/1/2010,則會解析1,其餘部分將被忽略。你可以通過看看你通過2/1/2010時是否得到2來檢驗假設。

解決方法似乎是使用getObjectValue:forString:range:error:

+0

爲什麼不能只是一個簡單的'int.Parse ()'call :) – 2010-11-04 11:04:50

+0

@Richard J. Ross III:你可以看看'NSDecimalNumber decimalNumberWithString:' – JeremyP 2010-11-04 11:26:22