왜 형식 인수로 NSInteger 변수를 캐스트해야합니까?


143
NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <==== 

위의 코드는 오류를 생성합니다 :

'NSInteger'유형의 값을 형식 인수로 사용해서는 안됩니다. 대신 'long'에 명시 적 캐스트를 추가하십시오.

수정 된 NSLog메시지는 실제로 NSLog(@"%lg", (long) myInt);입니다. 왜의 정수 값으로 변환해야합니까 myInt에를 long내가 디스플레이 값을 원한다면?


1
@DanielLee, 당신이 사용하는 경우 NSLog(@"%ld", (long) myInt);long캐스트가와 일치하는 것입니다 l의 규정 %ld,하지만 같은 그 모든 불필요 NSLog(@"%d", myInt);(충분한 우리가 볼 수 주어진 것입니다 myInt하지 않습니다 long. 결론적으로, 당신은 캐스트 myInt형식으로 긴 한정자 사용하는 경우 긴 문자열 형식 한정자를 사용하거나 long여기에서 캐스트 할 필요가 없습니다
Rob

1
분명히 NSLog (@ "% i", myInt); 위에 표시된 것처럼 오류 메시지가 표시되므로 충분합니다.
Daniel Lee

2
@DanielLee Martin R의 의견을 참조하십시오. iOS 태그를 사용하여 질문을 게시 했지만 (긴 길이 NSInteger아닙니다 ) OS X 대상 ( NSInteger long )으로 컴파일하는 것처럼 들립니다 .
Rob

아 알 겠어. 나는 iOS와 OSX가 NSInteger를 비트와 유형이 다른 것으로 만들지 몰랐습니다.
Daniel Lee

답변:


193

해당 플랫폼 에서 64 비트 정수 NSInteger로 정의되고 OS X (64 비트)에서 컴파일하는 경우이 경고가 표시됩니다 long. %i위한 포맷은, 다른 한편으로는, 인 int32 비트이다. 따라서 형식과 실제 매개 변수의 크기가 일치하지 않습니다.

이후 NSInteger32 비트 또는 64 비트 인, 플랫폼에 따라 컴파일러에 캐스팅 추가 권장 long일반적.

업데이트 : iOS 7은 이제 64 비트도 지원하므로 iOS를 컴파일 할 때 동일한 경고가 표시 될 수 있습니다.


1
iOS 7에서이 오류가 발생합니다. 오래 설정하면 최신 iPhone 5S 만 64 비트이므로 오래된 32 비트 장치에서 문제가 발생합니까?
Pritesh Desai

25
@BartSimpson :에서와 같이 명시 적으로 "길다" NSLog(@"%ld", (long) myInt)는 32 비트 및 64 비트에서 올바르게 작동합니다.
Martin R

우리가 캐스팅하는 경우 @MartinR, 왜 처음부터 오래 사용하지 않습니까?
윌리엄 Entriken

3
@FullDecent : 물론 긴 작업을 할 수 있습니다 : long myInt = [myNumber longValue];. 그러나 많은 (Core) Foundation 메서드는 NS (U) Integer를 매개 변수 또는 반환 값으로 사용하므로 일반적인 문제가 남아 있습니다. 또한 앱에서 NS (U) Integer를 사용하여 64 비트 장치에서 더 큰 범위를 얻는 것이 합리적입니다.
Martin R

39

형식 지정자가 데이터 유형과 일치하면 아무 것도 캐스트 할 필요가 없습니다. NSInteger기본 유형으로 정의되는 방법에 대한 자세한 내용은 Martin R의 답변을 참조하십시오 .

따라서 64 비트 환경 용으로 작성된 코드의 경우 다음과 같이 로그 문을 작성할 수 있습니다.

NSLog(@"%ld",  myInt); 

32 비트 환경에서는 다음과 같이 작성할 수 있습니다.

NSLog(@"%d",  myInt); 

캐스트없이 모두 작동합니다.

어쨌든 캐스트를 사용하는 한 가지 이유는 좋은 코드가 여러 플랫폼에 포팅되는 경향이 있기 때문에 변수를 명시 적으로 캐스팅하면 32 및 64 비트 모두에서 깨끗하게 컴파일됩니다.

NSLog(@"%ld",  (long)myInt);

그리고 이것은 결국 디버깅 보조 도구 인 NSLog 문뿐만 아니라 [NSString stringWithFormat:]프로덕션 코드의 합법적 인 요소 인 다양한 파생 메시지에도 적용됩니다.


1
이제이 해킹이 필요하므로 NSInteger를 처음 사용하는 것이 가장 좋은 방법입니까?
윌리엄 Entriken

@FullDecent 형식 문자열과 같이 런타임으로 해석되는 코드의 문제 일뿐입니다. 컴파일 된 코드는 NSInteger typedef를 이용합니다.
Monolo

그것 이다 그것은 정의되는 방식을 정의하는 이유 좋은 이유가 있기 때문에, NSInteger을 사용하는 것이 가장 좋습니다.
gnasher729 14

22

NSInteger를 NSLog로 전달하는 대신 NSNumber 만 전달하십시오. 이것은 모든 캐스트를 둘러보고 올바른 문자열 형식 지정자를 선택합니다.

NSNumber foo = @9000;
NSLog(@"foo: %@", foo);
NSInteger bar = 9001;
NSLog(@"bar: %@", @(bar));

NSUIntegers에서도 걱정할 필요가 없습니다. 혼합 64 비트 / 32 비트 환경에서 NSInteger 및 NSUInteger에 대한 답변보기


2
선택한 답변이 기술적으로 질문에 대한 최상의 답변이라고 생각하지만 각 발생을 피하고 경고를 방지하는 방법을 알고 싶다면 이것이 최선의 해결책이라는 것을 알 수 있습니다.
Daniel Wood

0

를 사용하는 동안 경고는 유지 NSLog(@"%ld", (long)myInt);하지만 long myInt = 1804809223;iOS 10에서 변경 선언 후 경고를 중지합니다 .


-2

OS X은 NSInteger, NSUInteger, CGFloat 및 CFIndex와 같은 여러 데이터 유형을 사용하여 32 비트 및 64 비트 환경에서 일관된 값을 나타내는 수단을 제공합니다. 32 비트 환경에서 NSInteger 및 NSUInteger는 각각 int 및 unsigned int로 정의됩니다. 64 비트 환경에서 NSInteger 및 NSUInteger는 각각 long 및 unsigned long으로 정의됩니다. 플랫폼에 따라 다른 printf 스타일 유형 지정자를 사용할 필요가 없도록 이 링크 에 표시된 지정자를 32 비트 및 64 비트 환경 모두 에 사용할 수 있습니다 .

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