2013-07-24 2 views
3

내 앱에 Constants.h 파일이 있습니다. 여기에서 쉽게 액세스 할 수 있도록 앱 전체에 적용 할 수있는 항목이 #define입니다. 그래도 iOS 버전을 기반으로하는 #define ing은 힘든 시간을 보내고 있습니다. 여기에 내가 무엇을 시도했다입니다 :iOS 버전을 기반으로 # 정의하는 방법은 무엇입니까?

#ifdef __IPHONE_7_0 

#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"]; 

#else 

#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait.png"]; 

#endif 

는 아이폰 OS 7이이 NDA, O 클로저 아래가 의미하는 것은 아니다라고해서!

iOS 7의 경우 이 적합합니다.입니다. 그러나 iOS 6에서 앱을 실행하면 #define은 여전히 ​​iOS 7 중 하나입니다. 마치 #ifdef이 고려되지 않은 것으로 보입니다.

이 문제를 해결하려면 어떻게해야합니까?

+4

이 작업을 수행 할 수 없습니다. iOS 버전은 컴파일 타임 결정이 아닌 런타임 결정이어야합니다. – rmaddy

+0

@rmaddy 죄송합니다! 나는 정상적으로 작동하지만 정상적인 코드에서는 작동하지만 #define은 작동하지 않는다고 생각합니다 ... – Undo

+0

Xcode의 두 가지 버전으로 코드를 빌드 할 수 없도록하는 경우가 아니라면 런타임 검사를 사용해야합니다. 시간 체크를 컴파일하지 않습니다. '# if'와'#define'은 모두 컴파일 타임 기능입니다. – rmaddy

답변

7

컴파일 타임 검사를 사용하는 대신 런타임 검사가 필요합니다. 즉, #define을 사용할 수 없습니다. iOS 버전에 따라 런타임에 초기화되는 정적 변수를 사용하는 것이 좋습니다. 다음은 단일 파일에서 값만 필요로하는 예제입니다.

일부하는 .m 파일 :

static UIImage *kHamburgerImage = nil; 

+ (void)initialize { 
    // This assumes you only support iOS 6 and later - adjust as needed 
    if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) { 
     kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"]; 
    } else { 
     kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"]; 
    } 
} 

편집 :

Constants.h : 이러한 전역 할 필요가 있기 때문에, 당신은이 작업을 수행해야

extern UIImage *kHamburgerImage; 

@interface Constants 
@end 

Constants.m :

UIImage *kHamburgerImage = nil; 

@implementation Constants 

+ (void)initialize { 
    // This assumes you only support iOS 6 and later - adjust as needed 
    if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) { 
     kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"]; 
    } else { 
     kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"]; 
    } 
} 

@end 

그러나 이것은 문제. 특정 단계를 수행하지 않으면이 전역에 액세스하면 nil 포인터가 될 수 있습니다. 클래스가 실제로 참조되는 경우에만 초기화됩니다. 나는 제안이의 첫 번째 줄에 같은 application:didFinishLaunchingWithOptions: 당신이 :

[Constants class]; 

이것은 호출되는 초기화를 보장하고 코드에서 다른 곳을 사용하기 전에 상수가 설정이다.

+0

So .. 내'Constants.h' 파일을'.m' 파일로 변경 하시겠습니까? – Undo

+0

글로벌 파일에서 사용되는 경우에는 Constants.h 및 Constants.m이 필요합니다. .h에서 이들을 'extern UIImage * kHamburgerImage;'라고 선언하십시오. 그런 다음 .m에서'static' 키워드를 제거하십시오. – rmaddy

+0

그리고 여전히'Constants.h' 파일을 가져 와서'kHamburgerImage'라고 부를 수 있습니까? – Undo

6

iOS 검사를 매크로로 정의하여 코드를 줄여도됩니다.

#define IS_IOS7 [[UIDevice currentDevice].systemVersion hasPrefix:@"7"] 

그리고 새로운 코드는 방법이 더 읽을 수

,

if (IS_IOS7) { 
    kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"]; 
} else { 
    kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"]; 
} 
+2

작동하지 않습니다! 컴파일시 IS_IOS7을 다음 코드로 바꿉니다. 그것은 읽을 수없는 코드가 무엇 이었을지를 만들어 낸다. –

2

당신은 #ifdef와 대신 #ifndef 사용해야합니다. 여기에 코드가 있습니다. 나는 그것이 당신을 도울 것이기를 바랍니다.

#ifndef __IPHONE_7_0 

#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"]; 

#else 

#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait.png"]; 

#endif 
+0

@Val 아니요,이 대답이 예상대로 작동 할 수있는 방법은 없습니다. 앱이 컴파일 될 때 오직 하나의'kHamburgerImage'가 정의 될 것입니다. 따라서 런타임시 iOS의 버전에 관계없이 모든 버전에서 단일 값이 사용됩니다. – rmaddy

+0

@rmaddy 동의합니다, 당신 말이 맞습니다. 이것은 시뮬레이터의 다른 SDK에서만 작동합니다. – Val

관련 문제