Objective-C中的动态原语

时间:2014-02-01 01:16:03

标签: objective-c types casting primitive

我有一个值存储为uint64_t(应用程序所需的最大值)。我需要用数字做整数数学,但是大小取决于用户指定的内容。

我需要一个函数,它接受一个uint64_t和一个转换为正确原语的位大小并返回它。

@interface EAEIntegerValue : NSObject <NSCopying>
@property uint64_t storageObject;

- (id)init;
- (id)initWithValue:(uint64_t)value;

- (uint64_t)getValueUInt64t;
- (int64_t)getValueInt64t;
- (uint32_t)getValueUInt32t;
- (int32_t)getValueInt32t;
- (uint16_t)getValueUInt16t;
- (int16_t)getValueInt16t;
- (uint8_t)getValueUInt8t;
- (int8_t)getValueInt8t;

// This is the function I am concerned with:
- (id)getValue:(uint8_t)bitSize;
@end

getValue的伪代码:

- (id)getValue:(uint8_t)bitSize {
    if (bitSize == 8) return [self getValueInt8t];
    if (bitSize == 16) return [self getValueInt16t];
    if (bitSize == 32) return [self getValueInt32t];
    if (bitSize == 64) return [self getValueInt64t];
    //...Unsigned...
    @throw...
}

我收到关于将原语作为id返回的投诉。我理解为什么我得到错误,但我没有看到将值包装为对象并保留函数的动态特性的方法。有必要保留正确的大小整数,并且不应期望调用它的函数手动执行此操作。调用函数可能如下所示:

- (EAEIntegerValue*)doMath:(int)bitSize {
    // It is important for this to be done in the correct bit size mode.
    uint64_t value = [val1 getValue:bitSize] / [val1 getValue:bitSize];

    // I don't care that it is casted back to a 64-bit int later.
    return [[EAEIntegerValue alloc] initWithValue:value];
}

最糟糕的情况是,我可以这样做(希望你能理解我为什么要避免它。我有20-30个这样的功能):

- (EAEIntegerValue*)doMath:(int)bitSize :(bool)isSigned {
    uint64_t value;
    if (bitSize == 8 && isSigned) value = [val1 getValueInt8t] / [val1 getValueInt8t];
    else if (bitSize == 8) value = [val1 getValueUInt8t] / [val1 getValueUInt8t];
    else if (bitSize == 16 && isSigned) value = [val1 getValueInt16t] / [val1 getValueInt16t];
    else if (bitSize == 16) value = [val1 getValueUInt16t] / [val1 getValueUInt16t];
    else if (bitSize == 32 && isSigned) value = [val1 getValueInt32t] / [val1 getValueInt32t];
    else if (bitSize == 32) value = [val1 getValueUInt32t] / [val1 getValueUInt32t];
    else if (bitSize == 64 && isSigned) value = [val1 getValueInt64t] / [val1 getValueInt64t];
    else if (bitSize == 64) value = [val1 getValueUInt64t] / [val1 getValueUInt64t];

    return [[EAEIntegerValue alloc] initWithValue:value];
}
哇,这是很多代码和很多单元测试!

1 个答案:

答案 0 :(得分:1)

您可以使用预处理器宏执行此操作。检查传入的值是一个很长的宏,但是你可以做一些......

#define getValue(obj, bitSize) ((bitSize) == 8 ? [obj getValueInt8t] : (...))