iOS 프로젝트의 Prefix.pch에 다양한 편의 매크로를 추가하는 많은 개발자를 보았습니다.
iOS Prefix.pch 파일에 추가 할 것을 권장하거나하지 않는 것이 무엇입니까? Prefix.pch는 어떻게 생겼습니까?
답변
Ewww… .pch 파일에 매크로를 넣지 마십시오! .pch 파일은 정의에 따라 프로젝트 별 미리 컴파일 된 헤더입니다. 프로젝트의 맥락을 넘어서서 사용해서는 안되며 #include
s와 #import
s 만 포함하면 안됩니다 .
당신은 몇 가지 매크로를 가지고 같은 당신은 자신의 헤더 파일에 그들을 스틱, 헤더 사이에 공유하고자하는 경우 – Common.h
및 – 또는 어떤 #include
것을 .PCH의 시작 부분에.
답변
최신 iOS 및 OS X의 경우 사람들은 Modules를 사용해야합니다 . 이것은 새 프로젝트에 대해 기본적으로 활성화되며 가져 오기 / 포함은 @import
.
모듈을 사용하면 컴파일러가 모듈 내용 (예 : 프레임 워크의 헤더)의 중간 표현을 만들 수 있습니다. PCH와 매우 유사하게이 중간 표현은 여러 번역에서 공유 될 수 있습니다. 그러나 모듈은 특정 대상이 아닐 수도 있고 선언을 지역화 할 필요가 없기 때문에 한 단계 더 나아갑니다 *.pch
. 이 표현은 당신에게 많은 중복 컴파일러 작업을 절약 할 수 있습니다.
모듈을 사용하면 PCH가 필요하지 않으며 @import
종속성에 대한 로컬 사용을 선호하여 모듈을 완전히 제거해야합니다 . 이 경우, PCH 만에서 당신을 절약 타이핑 (IMO 어쨌든 일을해야) 종속 로컬 흠.
이제 원래의 질문으로 돌아가 보면 : PCH를 모든 종류의 무작위로 채우는 것을 피해야합니다. 매크로, 상수, #defines
및 모든 종류의 작은 라이브러리. 일반적으로 대부분의 소스 파일에 실제로 불필요한 것은 생략 해야 합니다 . PCH에 모든 종류의 물건을 넣는 것은 무게와 의존성을 추가하는 것입니다. 나는 사람들이 그들이 연결하는 모든 것을 PCH에 넣는 것을 봅니다. 실제로 보조 프레임 워크는 일반적으로 대부분의 경우 몇 개의 번역에만 표시되어야합니다. 예는 “여기에 우리의 StoreKit 물건입니다 -하자의 수입 StoreKit 경우에만이 해야볼 수 있습니다. 특히,이 3 가지 번역 “. 이렇게하면 빌드 시간이 단축되고 종속성을 추적하는 데 도움이되므로 코드를 더 쉽게 재사용 할 수 있습니다. 따라서 ObjC 프로젝트에서는 일반적으로 Foundation에서 멈출 것입니다. UIKit 또는 AppKit을 PCH에 추가하는 것을 고려할 수 있습니다. 이는 모두 빌드 시간을 최적화하려는 경우입니다. 거의 모든 것을 포함하는 대형 PCH의 문제 중 하나는 불필요한 종속성을 제거하는 데 시간이 많이 걸린다는 것입니다. 프로젝트의 종속성이 증가하고 빌드 시간이 늘어 나면 빌드 시간을 줄이기 위해 불필요한 종속성을 제거하여 맞서 싸워야합니다. 또한 자주 변경되는 항목은 일반적으로 PCH에서 제외되어야합니다. 변경하려면 전체를 다시 빌드해야합니다. PCH를 공유하는 몇 가지 옵션이 있습니다. PCH를 사용하는 경우
PCH에 입력 한 내용에 대해서는 몇 년 전에 대부분의 대상에 대해 사용을 중단했습니다. 일반적으로 공통점이 충분하지 않습니다. 명심하세요, 저는 C ++, ObjC, ObjC ++ 및 C를 작성합니다. 컴파일러는 타겟의 각 언어에 대해 하나씩 내 보냅니다. 따라서이를 활성화하면 종종 컴파일 시간이 느려지고 I / O가 높아집니다. 궁극적으로, 의존성을 높이는 것은 복잡한 프로젝트에서 의존성을 퇴치하는 좋은 방법이 아닙니다. 여러 언어 / 방언으로 작업 할 때 주어진 대상에 필요한 종속성에 많은 차이가 있습니다. 아니요, 모든 프로젝트에 최적이라고 조언하지는 않지만 대규모 프로젝트의 종속성 관리에 대한 관점을 제공합니다.
참고 문헌
메모
- 이 질문은 원래 모듈이 도입되기 몇 년 전에 제기되었습니다.
- 현재 (Xcode 5.0) 모듈은 C 및 ObjC에서 작동하지만 C ++에서는 작동하지 않습니다.
답변
나는 bbum에 동의합니다. PCH 파일에 대한 필자의 견해는 #include
또는 #import
진술 만 포함해야한다는 것 입니다. 당신이 도움이, 높은 수준의 매크로 무리가 있다면 그래서, 같은 뭔가를 정의 Common.h
하고 #import
bbum 제안으로, 해당 파일.
나는 보통 한 단계 더 나아가 PCH 파일을 사용하여 #import
이라는 파일 XXCategories.h
(여기서 XX
포함 사용하는 클래스 이름 접두사 규칙입니다) #import
내 모든 UIKit 및 기초 클래스 범주들 : NSString+XXAdditions.h
, UIColor+XXAdditons.h
, 등
답변
“macros.h”헤더 파일 생성
이 헤더를 Prefix.pch로 가져옵니다.
이 macros.h에 모든 프레임 워크와 다른 중요한 것들을 넣습니다.
성능이 걱정 되더라도 걱정하지 마세요.
헤더 및 성능
마스터 헤더 파일을 포함하면 프로그램이 부 풀릴 수 있다고 걱정 되더라도 걱정하지 마십시오. OS X 인터페이스는 프레임 워크를 사용하여 구현되므로 이러한 인터페이스의 코드는 실행 파일이 아닌 동적 공유 라이브러리에 있습니다. 또한 프로그램에서 사용하는 코드 만 런타임에 메모리에로드되므로 메모리 내 공간도 마찬가지로 작게 유지됩니다. 컴파일 중에 많은 수의 헤더 파일을 포함하는 것에 대해서는 다시 한 번 걱정하지 마십시오. Xcode는 미리 컴파일 된 헤더 기능을 제공하여 컴파일 시간을 단축합니다. 모든 프레임 워크 헤더를 한 번에 컴파일하면 새 프레임 워크를 추가하지 않는 한 헤더를 다시 컴파일 할 필요가 없습니다. 그 동안에는 성능 저하가 거의 또는 전혀없이 포함 된 프레임 워크의 모든 인터페이스를 사용할 수 있습니다.
또한 내 macros.h에 다음과 같은 많은 상수를 넣었습니다.
// delegate
#define UIAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]
#define APPDELEGATE ((AppDelegate *)[[UIApplication sharedApplication] delegate])
// system
#define IS_IPHONE_4INCH (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height==568)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// screen size
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)
#define IS_RETINA_DISPLAY ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))
#define IS_PORTRAIT UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])
#define IS_LANDSCAPE UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])
//system version
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
// math
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
// cores
#define RGB(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
#define MAKECOLOR(R, G, B, A) [UIColor colorWithRed:((float)R/255.0f) green:((float)G/255.0f) blue:((float)B/255.0f) alpha:A]
#define MAKECOLORFROMHEX(hexValue) [UIColor colorWithRed: ((float)((hexValue & 0xFF0000) >> 16))/255.0 green:((float)((hexValue & 0xFF00) >> 8))/255.0 blue:((float)(hexValue & 0xFF))/255.0 alpha:1.0]
//customizations
#define SHOW_STATUS_BAR [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
#define HIDE_STATUS_BAR [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
#define SHOW_NAVIGATION_BAR [self.navigationController setNavigationBarHidden:FALSE];
#define HIDE_NAVIGATION_BAR [self.navigationController setNavigationBarHidden:TRUE];
#define VC_OBJ(x) [[x alloc] init]
#define VC_OBJ_WITH_NIB(x) [[x alloc] initWithNibName : (NSString *)CFSTR(#x) bundle : nil]
#define RESIGN_KEYBOARD [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
#define CLEAR_NOTIFICATION_BADGE [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
#define REGISTER_APPLICATION_FOR_NOTIFICATION_SERVICE [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]
#define HIDE_NETWORK_ACTIVITY_INDICATOR [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
#define SHOW_NETWORK_ACTIVITY_INDICATOR [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];