When to Use Nsinteger Vs. Int

When to use NSInteger vs. int

You usually want to use NSInteger when you don't know what kind of processor architecture your code might run on, so you may for some reason want the largest possible integer type, which on 32 bit systems is just an int, while on a 64-bit system it's a long.

I'd stick with using NSInteger instead of int/long unless you specifically require them.

NSInteger/NSUInteger are defined as *dynamic typedef*s to one of these types, and they are defined like this:

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

With regard to the correct format specifier you should use for each of these types, see the String Programming Guide's section on Platform Dependencies

int vs NSNumber vs NSInteger

NSInteger is a type definition that describes an integer - but it is NOT equivalent to int on 64-bit platforms.

You can examine the typedef by cmd-clicking on NSInteger in Xcode.

NSInteger is defined as int when building a 32-bit app and as long for 64-bit apps.

Most of the time you can replace int with NSInteger, but there are some things to consider when doing so.

Apple's 64-Bit Transition Guide for Cocoa has some information about that.

NSNumber is a class that helps you to store numeric types as object. It has methods to convert between different types and methods to retrieve a string representation of your numeric value.

If you use a variable day of type NSNumber* the way you did in your example, you are not modifying the value of day but its memory address.

If you are working with time values you also could take a look at NSDate.

NSNumber vs Int

As a generalization: Just stick with POD types until you need to use an object based representation, such as NSNumber. The performance is much better with the PODs, but you'll need NSNumber in some cases.

In some cases, it may make sense to use NSNumber instead -- this is typically when you reuse a NSNumber often -- this is to avoid making a ton of duplicate NSNumbers. Such occurrences are practical only rarely beyond serialization and generic objc interfaces (bindings, transformers, dictionaries).


Update/Details: The ObjC runtime will in some cases, on some architectures, and on some OS versions substitute a tagged pointer representing NSNumbers of specific type and domain. Although the internal representation has changed since originally written a few years back, here is a good introduction to the subject: http://objectivistc.tumblr.com/post/7872364181/tagged-pointers-and-fast-pathed-cfnumber-integers-in. Where this can be used, it saves you from slow operations like allocations, locking, and ref count ops. Nevertheless, tagged pointers are incapable of representing every number and it introduces overhead, so you should still favor basic builtins over NSNumber as a default. Tagged pointers are a great optimization where applicable, but are far from competing with the builtins when you just need a number.

Objective C - when to use NSNumber vs a Primitive

NSNumber is somewhat rare in Objective-C. Certainly not unheard of, but somewhat rare. If you're in doubt, you want to use NSInteger. I've written whole, large programs without a single NSNumber in them.

The most common use for NSNumber is when you want to put it into an NSArray, NSDictionary or serialize it (for example into NSUserDefaults). Most of the time, numbers are just a property of some other object, as an NSInteger.

What's the difference between NSNumber and NSInteger?

The existing answers are useful; adding to them:

Yes, NSUInteger gives twice the range among positive integers as NSInteger, but I think another critical reason to choose between the two is simply to distinguish among cases where negative values simply do not make sense.

Example: the return value of NSArray's count method is an NSUInteger, which makes sense since we cannot have an array with a negative number of elements. When the coder knows it's unsigned, he/she has more freedom to perform operations that might be unreliable in the signed case, including bitwise operations such as shifting. This blog post talks more about signed vs unsigned.

My guess about CGFloat vs NSFloat (which doesn't exist): It might be the case that the designers of the NeXTStep-named code elements simply didn't need to specify too many float values, outside of time intervals. So they gave NSTimeInterval, which is a floating-point type, but that is clearly intended for use with time intervals. And, frankly, it's great to have that type because you know it's always meant to be in seconds without having to deal with a struct. When you move into the graphics world (where Core Graphics lives), suddenly floats are all around you, hovering in the air (haha). So it makes sense to introduce a CGFloat there. This paragraph is all "educated speculation."

Also, just to be clear about why you might use NSInteger etc instead of primitive types: Because this way it's easier to write portable code that takes full advantage of the machine architecture. For example, a CGFloat uses 32 bits on some machines and 64 bits on others, depending largely on how much of an efficiency gap there is on those machines for those sizes. In some cases, there's no real speedup for using 32 bits vs 64 bits, so you might as well use 64 bits. If you've declared things as CGFloat's, you suddenly get that extra precision "for free" when you recompile.

And, as iKenndac has pointed out, NSNumber is a wrapper class for all of these (and other primitive or quasi-primitive types like the BOOL) which enables you to include it in your NSArrays and NSDictionarys, archive them more easily, and do other things that NSObjects can do.

Benefits of using NSInteger over int?

I personally think that, 64-bit is actually the reason for existence for NSInteger and NSUInteger; before 10.5, those did not exist. The two are simply defined as longs in 64-bit, and as ints in 32-bit.

NSInteger/NSUInteger are defined as *dynamic typedef*s to one of these types, and they are defined like this:

#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

Thus, using them in place of the more basic C types when you want the 'bit-native' size.

I suggest you to throughly read this link.
CocoaDev has some more info.

For proper format specifier you should use for each of these types, see the String Programming Guide's section on Platform Dependencies

NSInteger vs int vs object

It does sound like you've made it overly complex. Obviously, the idea is not really "there is a variable named totalSave" since the user could care less about where you store it, and from the rest of your post, you actually don't care about how you store it.

That said, in order to make this a bit more concrete, let's think about a "total score" state that numerous parts of the program might add to. There are a couple of approaches you might take. In any case, you likely have some object somewhere that is keeping track of the score. We'll call it the Game object, but it could be a Level or whatever.

So there are three big schools of thought: you can pass this Game object around to everyone, you can have a Game singleton, or you can use notifications. Each of these approaches has advantages, and any one you pick is probably fine for a simple program (personally, for a very simple program, I'd use a singleton).

In the first scheme, at some point in the program you create a Game object that has some addToScore: method. You assign this object as a property on every other object that needs to update the score. Each of those calls [self.game addToScore:value]. This approach makes unit testing a bit simpler, but can be a bit tedious to implement.

In the second scheme, you have some shared singleton +[Game sharedGame]. When you want to update the score, call [[Game sharedGame] addToScore:value]. This is generally the easiet to implement.

In the third scheme, you have some object (Game) that uses NSNotificationCenter to observe some notification. When you want to update the score, you just post a notification that includes the amount to add in its user dictionary. This is great for keeping things extremely decoupled, but again can be a little tedious in the more usual case.

But as @Chuck notes, you're probably over-thinking this, and you may want to go back and work through some of the tutorials to get a better sense of how these things usually work. The kind of situation you're describing is not very complicated.

NSInteger vs 64-bit architecture on iOS

Your point about using types from the <stdint.h> header of C99 is absolutely valid: these types give you more control over the size of your integral types. The NS-prefixed integral types, however, predate the standardization of <stdint.h>, hence introducing a parallel set of abstractions.

I use NS-prefixed integral types when interacting with Cocoa methods. For example, if Cocoa method returns NSUinteger, I declare my variable using NSUinteger type as well.

I use <stdint.h> types for variables in my program when I need precise control over the size of the stored data. Items that end up in Core Data are in this category.

When the size of an integral type does not matter, for example, when I need a loop control variable in a for loop, I use int.



Related Topics



Leave a reply



Submit