Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 502 Vote(s) - 3.42 Average
  • 1
  • 2
  • 3
  • 4
  • 5
When to use NSInteger vs. int

#1
When should I be using `NSInteger` vs. int when developing for iOS? I see in the Apple sample code they use `NSInteger` (or `NSUInteger`) when passing a value as an argument to a function or returning a value from a function.

- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...

But within a function they're just using `int` to track a value

for (int i; i < something; i++)
...

int something;
something += somethingElseThatsAnInt;
...

I've read (been told) that `NSInteger` is a safe way to reference an integer in either a 64-bit or 32-bit environment so why use `int` at all?
Reply

#2
If you dig into NSInteger's implementation:

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
#endif

Simply, the NSInteger typedef does a step for you: if the architecture is 32-bit, it uses `int`, if it is 64-bit, it uses `long`. Using NSInteger, you don't need to worry about the architecture that the program is running on.
Reply

#3
OS X is "LP64". This means that:

`int` is always 32-bits.

`long long` is always 64-bits.

`NSInteger` and `long` are always pointer-sized. That means they're 32-bits on 32-bit systems, and 64 bits on 64-bit systems.


The reason NSInteger exists is because many legacy APIs incorrectly used `int` instead of `long` to hold pointer-sized variables, which meant that the APIs had to change from `int` to `long` in their 64-bit versions. In other words, an API would have different function signatures depending on whether you're compiling for 32-bit or 64-bit architectures. `NSInteger` intends to mask this problem with these legacy APIs.

In your new code, use `int` if you need a 32-bit variable, `long long` if you need a 64-bit integer, and `long` or `NSInteger` if you need a pointer-sized variable.

Reply

#4
*Why use `int` at all?*

Apple uses `int` because for a loop control variable (which is only used to control the loop iterations) `int` datatype is fine, both in datatype size and in the values it can hold for your loop. **No need for platform dependent datatype here.** For a loop control variable even a 16-bit `int` will do most of the time.

Apple uses `NSInteger` for a function return value or for a function argument **because in this case datatype [size] matters**, because what you are doing with a function is communicating/passing data with other programs or with other pieces of code; see the answer to *When should I be using NSInteger vs int?* in your question itself...

> they [Apple] use NSInteger (or NSUInteger) *when passing a value* as an
> argument to a function *or returning a value* from a function.
Reply

#5
You should use NSIntegers if you need to compare them against constant values such as NSNotFound or NSIntegerMax, as these values will differ on 32-bit and 64-bit systems, so index values, counts and the like: use NSInteger or NSUInteger.

It doesn't hurt to use NSInteger in most circumstances, excepting that it takes up twice as much memory. The memory impact is very small, but if you have a huge amount of numbers floating around at any one time, it might make a difference to use ints.

If you DO use NSInteger or NSUInteger, you will want to cast them into long integers or unsigned long integers when using format strings, as new Xcode feature returns a warning if you try and log out an NSInteger as if it had a known length. You should similarly be careful when sending them to variables or arguments that are typed as ints, since you may lose some precision in the process.

On the whole, if you're not expecting to have hundreds of thousands of them in memory at once, it's easier to use NSInteger than constantly worry about the difference between the two.
Reply

#6
As of currently (September 2014) I would recommend using `NSInteger/CGFloat` when interacting with iOS API's etc if you are also building your app for arm64.
This is because you will likely get unexpected results when you use the `float`, `long` and `int` types.



**EXAMPLE: FLOAT/DOUBLE vs CGFLOAT**

As an example we take the UITableView delegate method `tableView:heightForRowAtIndexPath:`.

In a 32-bit only application it will work fine if it is written like this:

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}

`float` is a 32-bit value and the 44 you are returning is a 32-bit value.
However, if we compile/run this same piece of code in a 64-bit arm64 architecture the 44 will be a 64-bit value. Returning a 64-bit value when a 32-bit value is expected will give an unexpected row height.

You can solve this issue by using the `CGFloat` type

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}

This type represents a 32-bit `float` in a 32-bit environment and a 64-bit `double` in a 64-bit environment. Therefore when using this type the method will always receive the expected type regardless of compile/runtime environment.

The same is true for methods that expect integers.
Such methods will expect a 32-bit `int` value in a 32-bit environment and a 64-bit `long` in a 64-bit environment. You can solve this case by using the type `NSInteger` which serves as an `int` or a `long` based on the compile/runtime environemnt.

Reply

#7
On iOS, it currently does not matter if you use `int` or `NSInteger`. It will matter more if/when iOS moves to 64-bits.

Simply put, `NSInteger`s are `int`s in 32-bit code (and thus 32-bit long) and `long`s on 64-bit code (`long`s in 64-bit code are 64-bit wide, but 32-bit in 32-bit code). The most likely reason for using `NSInteger` instead of `long` is to not break existing 32-bit code (which uses `int`s).

`CGFloat` has the same issue: on 32-bit (at least on OS X), it's `float`; on 64-bit, it's `double`.

**Update:** With the introduction of the iPhone 5s, iPad Air, iPad Mini with Retina, and iOS 7, you can now build 64-bit code on iOS.

**Update 2:** Also, using `NSInteger`s helps with Swift code interoperability.
Reply

#8
int = 4 byte (fixed irrespective size of the architect)
NSInteger = depend upon size of the architect(e.g. for 4 byte architect = 4 byte NSInteger size)
Reply

#9
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][1]


[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through