2

I've created two apps, call them server and client. The xcode projects for both of these apps use common sub-projects. The apps are designed for a specific customer to run on iOS7/iPad

For testing, I am compiling the server app and running it on an iPad 3. The client app is running on an Air. Xcode throws up a bunch of warnings when I compile for the iPad3 and its because the NSInteger/NSUInteger types are 32 bit and the logic I'm using (in this case NSString with format %lu) is complaining (because it was written for 64bit)

But even more troubling is that I use NSKeyArchiving to package data from one iPad to send to the other - I'm guessing I'm going to run into an issue if the data stored in these types exceeds 32 bits.

It looks like I need to standardise on another base type such as UInt32 rather than NSUInteger - is that right approach? Any other tips?

EDIT: Here's one example:

+ (NSUInteger)nextTransactionNumber
{
    static int64_t currentTransactionNumber = 0;
    OSAtomicIncrement64(&currentTransactionNumber);
    return currentTransactionNumber;
}

This compiles fine for 64bit, but has grief on the return for 32bit. So am I better to use Uint32?

300baud
  • 540
  • 4
  • 17
  • You should be able to fix that by placing (long) in front of the integers-- toll-free bridging will quiet 32-bit concerns most of the time. – AMayes Feb 25 '14 at 00:08
  • If there is any data being sent between machines, even if unneccisary, it is good practice to standardize size (uint32_t, uint64_t) and byte order (using ntohl, ntohs, etc.). – Linuxios Feb 25 '14 at 00:20

1 Answers1

0

NSNumber is a good option.

You can serialize it, deserialize it, print it all without 32/64 bit issues (that is unless you plan on working with numbers greater than 4 Billion).

NSNumber *number = @1000U;

To print out:

NSString *string = [NSString stringWithFormat:@"%@", number];

For calculations:

NSUInteger value = [number unsignedIntegerValue];

Archiving:

- (void)encodeWithCoder:(NSCoder *)encoder {
    // …
    [encoder encodeObject:self.number forKey:@"number"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self) {
        // …
        _number = [decoder decodeObjectForKey:@"number"];
    }
    return self;
}
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • Thanks @Jeffery, I do use this elsewhere in my app but don't use it exclusively - have preferred to use encodeInt64. Are you suggesting that using NSNumber abstraction throughout is a better pattern to adopt? – 300baud Feb 25 '14 at 00:39
  • 1
    @300baud Well NSNumber, NSInteger, CGFloat, etc. all support 64 bit AND 32 bit. I just use those to prevent any performance impacts. A good question to look at is this: http://stackoverflow.com/questions/4445173/when-to-use-nsinteger-vs-int – Nate Lee Feb 25 '14 at 00:45
  • @300baud NSNumber does all the work for you with regards to storing and persisting. If you need an object to hold a number, it a great option. – Jeffery Thomas Feb 25 '14 at 11:43
  • @nlee918 [premature optimization is the root of all evil](http://en.wikipedia.org/wiki/Optimization_(computer_science)#When_to_optimize) —Knuth – Jeffery Thomas Feb 25 '14 at 11:44