NSInteger와 int를 사용하는 경우


344

NSIntegeriOS 용으로 개발할 때 언제 int를 사용해야 합니까? Apple 샘플 코드 에서 값을 함수에 인수로 전달하거나 함수에서 값을 반환 할 때 사용하는 NSInteger(또는 NSUInteger) 코드를 봅니다.

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

그러나 함수 내에서 그들은 단지 int값을 추적하기 위해 사용하고 있습니다.

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

int something;
something += somethingElseThatsAnInt;
...

NSInteger64 비트 또는 32 비트 환경에서 정수를 참조하는 안전한 방법 이라는 것을 읽었습니다 (왜 들었 int습니까).

답변:


322

일반적으로 NSInteger코드가 실행될 프로세서 아키텍처의 종류를 모르는 경우 에 사용하려고 하므로 어떤 이유로 든 32 비트 시스템 int에서 64 비트 인 동안 가능한 가장 큰 정수 유형을 원할 수 있습니다. 시스템 long입니다.

특별히 요구하지 않는 한 / NSInteger대신 사용을 고수 합니다.intlong

NSInteger/ NSUIntegertypedef다음 유형 중 하나에 대한 * dynamic * s로 정의되며 다음과 같이 정의됩니다.

#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

이러한 각 유형에 사용해야하는 올바른 형식 지정자와 관련하여 플랫폼 종속성에 대한 문자열 프로그래밍 안내서 섹션을 참조하십시오.


4
또한 int 또는 long int가 필요하지 않으면 NSInteger를 사용하는 것이 가장 좋습니다.
v01d

4
@Shizam를 사용하는 int것이 더 적합 할 수도 있습니다 long. 어쩌면 당신은 그것이 특정 범위를 초과하지 않을 것이므로, 단순히 사용하는 것이 더 메모리 효율적이라고 생각할 것입니다 int.
Jacob Relkin

58
이 답변에 동의하지 않습니다. 내가 사용할 유일한 것은 NSInteger값을 지정하는 API로 값을 전달하는 것입니다. 그 외에는 int 또는 long에 비해 이점이 없습니다. 적어도 int 또는 long을 사용하면 printf 또는 유사한 명령문에 사용할 형식 지정자를 알고 있습니다.
JeremyP

3
오랫동안 저장해야하고 64b 시스템에서 작업하는 동안 NSInteger를 사용하지만 다른 사용자가 32b 시스템을 사용하면 어떻게됩니까? 실패는 눈치 채지 못하지만 사용자는 알게됩니다.
아리엘 카 무스

14
이것은 거꾸로입니다. 특별한 이유가없는 한 항상 int를 사용하십시오. 간단한 정수에 플랫폼 별 정의를 사용하면 코드를 읽기가 어려워집니다.
Glenn Maynard 님

44

int전혀 사용하지 않습니까?

애플은 int 루프 제어 변수 (루프 반복을 제어하는 ​​데만 사용됨) int데이터 유형이 데이터 유형 크기와 루프에 대해 보유 할 수있는 값 모두에 적합하기 때문에 사용합니다. 여기에서 플랫폼 종속 데이터 유형이 필요하지 않습니다. 루프 제어 변수의 경우 16 비트라도 int대부분의 시간을 수행합니다.

애플은 NSInteger 함수 반환 값 또는 함수 인수 에 사용합니다.이 경우 데이터 유형 [size]가 중요 하기 때문에 함수로 수행하는 작업은 다른 프로그램이나 다른 코드와 데이터를 통신 / 전달하기 때문입니다. NSInteger와 int언제 사용해야합니까?에 대한 답변을 참조하십시오 . 당신의 질문 자체에서 ...

[Apple] 은 함수에 을 인수로 전달 하거나 함수 에서 값반환 할 때 NSInteger (또는 NSUInteger)를 사용 합니다.


32

OS X은 "LP64"입니다. 이것은 다음을 의미합니다.

int 항상 32 비트입니다.

long long 항상 64 비트입니다.

NSInteger그리고 long항상 포인터 크기입니다. 이는 32 비트 시스템에서 32 비트이고 64 비트 시스템에서 64 비트임을 의미합니다.

NSInteger가 존재하는 이유는 포인터 크기의 변수를 보유 하는 int대신 많은 레거시 API가 잘못 사용 long되어 API가 64 비트 버전에서 로 변경 int되어야하기 때문 long입니다. 다시 말해, API는 32 비트 또는 64 비트 아키텍처를 위해 컴파일하는지에 따라 다른 함수 서명을 갖습니다. NSInteger이러한 레거시 API로이 문제를 숨기려고합니다.

새 코드에서 int32 비트 변수 long long가 필요한 경우, 64 비트 정수 가 필요한 경우 long또는 NSInteger포인터 크기의 변수가 필요한 경우 사용하십시오.


25
역사는 제자리에 있지만 조언은 끔찍합니다. 32 비트 변수가 필요한 경우을 사용하십시오 int32_t. 64 비트 정수가 필요한 경우을 사용하십시오 int64_t. 포인터 크기의 변수가 필요한 경우을 사용하십시오 intptr_t.
Stephen Canon

5
Stephen, 당신의 조언은 절대 int, long 또는 NSInteger를 사용하지 않는 것입니까?
Darren

7
아니요, 정수 유형의 고정 크기가 필요한 경우 절대로 사용하지 않는 것이 좋습니다. 그만큼<stdint.h>유형은 그 목적을 위해 존재한다.
Stephen Canon

3
Stephen, 내 대답은 "32 비트 정수의 크로스 플랫폼 유형 이름은 무엇입니까"가 아니라 "NSInteger vs int 사용시기"라는 질문에 대한 답변이었습니다. 누군가 NSInteger와 int 사이를 결정하려고하면 그들이 지원하는 플랫폼에서 얼마나 큰지 알 수 있습니다.
Darren

1
또한 이것이 64 비트 LP64임을 보장하지는 않습니다 long long. LP64플랫폼하도록 선택할 수있는 long long128 비트 정수.
Stephen Canon

26

NSInteger의 구현을 파헤 치면 :

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

NSInteger typedef는 간단히 단계를 수행합니다. 아키텍처가 32 비트 인 경우을 사용하고 int, 64 비트 인 경우을 사용합니다 long. NSInteger를 사용하면 프로그램이 실행되는 아키텍처에 대해 걱정할 필요가 없습니다.


14
NSInteger의 올바른 형식 지정자는 아키텍처에 따라 다르므로 걱정할 필요가 없습니다.
JeremyP

Apple 매뉴얼에 따르면 가장 간단한 방법은 값을 가장 큰 숫자 유형으로 변환하는 것 long long입니다. 따라서 모든 숫자 유형은 동일한 유형 지정자를 사용합니다.
Eonil

6
이제 가장 간단한 형식 지정 방법은 바로 상자에 넣는 것입니다. –NSLog("%@", @(1123));
Eonil

1
당신은 또한 그것을 던질 수 있습니다 :NSLog("%li", (long)theNSInteger);
Daniel

캐스팅은 나를 슬프게한다
tomalbrc

9

NSNotFound 또는 NSIntegerMax와 같은 상수 값과 비교해야하는 경우 NSInteger를 사용해야합니다.이 값은 32 비트 및 64 비트 시스템에서 다르므로 인덱스 값, 개수 등은 NSInteger 또는 NSUInteger를 사용하십시오.

NSInteger를 사용하는 것은 두 배의 메모리를 차지한다는 점을 제외하면 대부분의 환경에서 사용하는 것이 좋습니다. 메모리 영향은 매우 작지만 한 번에 많은 수의 숫자가 떠 다니면 int를 사용하는 데 차이가 생길 수 있습니다.

NSInteger 또는 NSUInteger를 사용하는 경우 형식 문자열을 사용할 때 NSInteger가 알려진 길이를 가진 것처럼 NSInteger를 로그 아웃하려고하면 경고를 반환하므로 형식 문자열을 사용할 때 정수 또는 부호없는 정수로 캐스트하려고합니다. int로 입력 된 변수 나 인수로 변수를 보낼 때 비슷하게주의해야합니다. 프로세스에서 정밀도가 떨어질 수 있기 때문입니다.

전체적으로 한 번에 수십만 개의 메모리가 메모리에 없을 것으로 예상되면 NSInteger를 사용하는 것이 두 가지의 차이점에 대해 끊임없이 걱정하는 것보다 쉽습니다.


9

현재 (2014 년 9 월 현재) NSInteger/CGFloatarm64 용 앱을 빌드하는 경우 iOS API 등과 상호 작용할 때 사용하는 것이 좋습니다 . 당신이 사용할 때 가능성이 예상치 못한 결과를 얻을 수 있기 때문입니다 float, long그리고 int유형을.

예 : 플로트 / 더블 대 CGFLOAT

예를 들어 UITableView 대리자 메소드를 사용 tableView:heightForRowAtIndexPath:합니다.

32 비트 전용 응용 프로그램에서는 다음과 같이 작성하면 제대로 작동합니다.

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

float는 32 비트 값이고 반환하는 44는 32 비트 값입니다. 그러나 64 비트 arm64 아키텍처에서 동일한 코드를 컴파일 / 실행하면 44가 64 비트 값이됩니다. 32 비트 값이 예상 될 때 64 비트 값을 반환하면 예기치 않은 행 높이가 제공됩니다.

CGFloat유형 을 사용하여이 문제를 해결할 수 있습니다

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

이 유형은 32 float비트 환경에서 32 비트와 64 비트 를 나타냅니다.double 를, 64 비트 환경에서 64 를 나타냅니다. 따라서이 유형을 사용할 때 메소드는 컴파일 / 런타임 환경에 관계없이 항상 예상 된 유형을 수신합니다.

정수를 기대하는 메소드도 마찬가지입니다. 이러한 방법은 int32 비트 환경에서 32 비트 값을, 64 비트 환경에서 64 비트 값을 예상 long합니다. 컴파일 / 런타임 환경을 기반으로 또는 유형 NSInteger을 제공 하는 유형 을 사용하여이 경우를 해결할 수 있습니다 .intlong


이 특정 변수의 값에 큰 값을 포함 할 수 없으므로 int를 사용하려면 어떻게해야합니까? 64 비트 환경에서 모두 잘 작동합니까? 다음과 같은 for 루프를 보지 못 했으므로 나는 그것이 또한 좋아야한다고 생각한다 : for (int i = 0; i <10; i ++) 환경에 상관없이 잘못된 행동을하고있다.
Chanchal Raj

@Chanchal Raj 다른 유형으로의 캐스트 나 변환, 또는 해당 변수와 관련된 타사 클래스 및 메소드의 사용 / 재정의가없는 한 NSInteger 대신 int를 사용하는 것이 좋습니다.
레온 루카 디

9

당신이 사용하는 경우 iOS의 경우는 현재 중요하지 않습니다 int또는 NSInteger. iOS가 64 비트로 이동하면 더 중요합니다.

간단히 말해서, NSIntegerS는 int32 비트 코드들 (및 32 비트 길이) 및 long64 비트 코드를 S ( longS는 64 비트 코드의 64 비트 폭이지만, 32 비트 코드에 32 비트). NSInteger대신에 사용 하는 가장 큰 이유 long는 기존 32 비트 코드 ( ints 를 사용 )를 중단하지 않기 때문입니다 .

CGFloat같은 문제가 있습니다 : 32 비트 (적어도 OS X의 경우)에서 float; 64 비트에서는 double입니다.

업데이트 : iPhone 5s, iPad Air, iPad Mini (Retina 포함) 및 iOS 7의 도입으로 이제 iOS에서 64 비트 코드를 작성할 수 있습니다.

업데이트 2 : 또한 NSIntegers를 사용 하면 Swift 코드 상호 운용성에 도움이됩니다.


0

int = 4 바이트 (건축가의 고정 크기와 무관) NSInteger = 건축가의 크기에 따라 다릅니다 (예 : 4 바이트 건축가의 경우 = 4 바이트 NSInteger 크기)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.