How to determine the true data type of an NSNumber?

前端 未结 4 1486
悲哀的现实
悲哀的现实 2020-12-02 00:22

Consider this code:

NSNumber* interchangeId = dict[@\"interchangeMarkerLogId\"];
long long llValue = [interchangeId longLongValue];
double dValue = [intercha         


        
4条回答
  •  暖寄归人
    2020-12-02 01:19

    As documented in NSDecimalNumber.h, NSDecimalNumber always returns "d" for it's return type. This is expected behavior.

    - (const char *)objCType NS_RETURNS_INNER_POINTER;
        // return 'd' for double
    

    And also in the Developer Docs:

    Returns a C string containing the Objective-C type of the data contained in the
    receiver, which for an NSDecimalNumber object is always “d” (for double).
    

    CFNumberGetValue is documented to return false if the conversion was lossy. In the event of a lossy conversion, or when you encounter an NSDecimalNumber, you will want to fall back to using the stringValue and then use sqlite3_bind_text to bind it (and use sqlite's column affinity).

    Something like this:

    NSNumber *number = ...
    BOOL ok = NO;
    
    if (![number isKindOfClass:[NSDecimalNumber class]]) {
        CFNumberType numberType = CFNumberGetType(number);
    
        if (numberType == kCFNumberFloat32Type ||
            numberType == kCFNumberFloat64Type ||
            numberType == kCFNumberCGFloatType)
        {
            double value;
            ok = CFNumberGetValue(number, kCFNumberFloat64Type, &value);
    
            if (ok) {
                ok = (sqlite3_bind_double(pStmt, idx, value) == SQLITE_OK);
            }
    
        } else {
            SInt64 value;
            ok = CFNumberGetValue(number, kCFNumberSInt64Type, &value);
    
            if (ok) {
                ok = (sqlite3_bind_int64(pStmt, idx, value) == SQLITE_OK);
            }
        }
    }
    
    // We had an NSDecimalNumber, or the conversion via CFNumberGetValue() was lossy.
    if (!ok) {
        NSString *stringValue = [number stringValue];
        ok = (sqlite3_bind_text(pStmt, idx, [stringValue UTF8String], -1, SQLITE_TRANSIENT) == SQLITE_OK);
    }
    

提交回复
热议问题