开发者

How should I declare a long in Objective-C? Is NSInteger appropriate?

I see NSInteger is used quite often and the typedef for it on the iPhone is a long, so technically I could use it when I am expect int(64) values. But should I be more expl开发者_运维问答icit and use something like int64_t or long directly? What would be the downside of just using long?


IIRC, long on the iPhone/ARM is 32 bits. If you want a guaranteed 64-bit integer, you should (indeed) use int64_t.


Integer Data Types Sizes

  • short - ILP32: 2 bytes; LP64: 2 bytes

  • int - ILP32: 4 bytes; LP64: 4 bytes

  • long - ILP32: 4 bytes; LP64: 8 bytes

  • long long - ILP32: 8 bytes; LP64: 8 bytes

It may be useful to know that:

The compiler defines the __LP64__ macro when compiling for the 64-bit runtime.

NSInteger is a typedef of long so it will be 32-bits in a 32-bit environment and 64-bits in a 64-bit environment.

When converting to 64-bit you can simply replace all your ints and longs to NSInteger and you should be good to go.

Important: pay attention to the alignment of data, LP64 uses natural alignment for all Integer data types but ILP32 uses 4 bytes for all Integer data types with size equal to or greater than 4 bytes.

You can read more about 32 to 64 bit conversion in the Official 64-Bit Transition Guide for Cocoa Touch.

Answering you questions:

How should I declare a long in Objective-C? Is NSInteger appropriate?

You can use either long or NSInteger but NSInteger is more idiomatic IMHO.

But should I be more explicit and use something like int64_t or long directly?

If you expect consistent 64-bit sizes neither long nor NSInteger will do, you'll have to use int64_t (as Wevah said).

What would be the downside of just using long?

It's not idiomatic and you may have problems if Apple rolls out a new architecture again.


If you need a type of known specific size, use the type that has that known specific size: int64_t.

If you need a generic integer type and the size is not important, go ahead and use int or NSInteger.


NSInteger's length depends on whether you are compiling for 32 bit or 64 bit. It's defined as long for 64 bit and iPhone and int for 32 bit.

So on iPhone the length of NSInteger is the same as the length of a long, which is compiler dependent. Most compilers make long the same length as the native word. i.e. 32 bit for 32 bit architectures and 64 bit for 64 bit architectures.

Given the uncertainty over the width of NSInteger, I use it only for types of variables to be used in the Cocoa API when NSInteger is specified. If I need a fixed width type, I go for the ones defined in stdint.h. If I don't care about the width I use the C built in types


If you want to declare something as long, declare it as long. Be aware that long can be 32 or 64 bit, depending on the compiler.

If you want to declare something to be as efficient as possible, and big enough to count items, use NSInteger or NSUInteger. Note that both can be 32 or 64 bits, and can be actually different types (int or long), depending on the compiler. Which protects you from mixing up types in some cases.

If you want 32 or 64 bit, and nothing else, use int32_t, uint32_t, int64_t, uint64_t. Be aware that either type can be unnecessarily inefficient on some compiler.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜