iOS Prefix.pch最佳实践

时间:2010-05-16 19:49:01

标签: ios objective-c xcode pch

我见过很多开发人员为他们的iOS项目的Prefix.pch添加各种便利宏。

您建议添加到iOS Prefix.pch文件中(或不建议)?你的Prefix.pch是什么样的?

4 个答案:

答案 0 :(得分:121)

Ewww ...不要将宏放在.pch文件中!根据定义,.pch文件是项目特定的预编译头。它确实不应该在项目的上下文之外使用,除了#include#import之外,它实际上不应该包含任何内容。

如果你有一些宏,并且想要在标题之间共享,那么将它们粘贴在他们自己的头文件中 - Common.h或其他 - 和#include 在.pch的开头。

答案 1 :(得分:36)

对于现代iOS和OS X,人们应该使用模块。默认情况下,这对新项目启用,导入/包含是使用@import完成的。

模块允许编译器创建模块内容的中间表示(例如框架的头部)。与PCH非常相似,这种中间表示可以跨多个翻译共享。但模块更进一步,因为模块不一定是特定于目标的,并且它们的声明不需要本地化(到*.pch)。这种表示可以为您节省大量的冗余编译工作。

使用模块,您不需要PCH,您可能应该完全取消它们 - 支持使用@import本地依赖项。在这种情况下,PCH只会让你免于输入依赖项的本地包含(你应该做的IMO)。

现在,如果我们回顾一下原来的问题:你应该避免给你的PCH填充各种随机的东西;宏,常量,#defines和各种小库。通常,您应该省略对大多数源文件不必要的内容。将各种各样的东西放在你的PCH中只是增加了一堆重量和依赖性。我看到人们将他们所链接的所有东西都放在了PCH中。实际上,在大多数情况下,辅助框架通常只需要对少数翻译可见。例如。 “这是我们的StoreKit东西 - 让我们只在必须可见的地方导入StoreKit。具体来说,这3个翻译”。这可以缩短您的构建时间,并帮助您跟踪您的依赖关系,以便您可以更轻松地重用代码。所以在一个ObjC项目中,你通常会停在基金会。如果有很多UI,那么您可以考虑将UIKit或AppKit添加到您的PCH。这都是假设您希望优化构建时间。包含(几乎)所有内容的大型PCH的问题之一是删除不必要的依赖性非常耗时。一旦项目的依赖关系增长并且构建时间增加,您需要通过消除不必要的依赖关系来反击,以减少构建时间。此外,任何经常变化的事情通常都应该远离您的PCH。更改需要完全重建。有一些共享PCH的选项。如果您使用PCH,请确保支持共享。

就我在PCH中所说的内容:几年前我停止使用它们用于绝大多数目标。通常没有足够的共同资格。请记住,我编写C ++,ObjC,ObjC ++和C - 编译器为目标中的每个lang发出一个。因此,启用它们通常会导致编译时间变慢和I / O增加。最终,增加依赖性并不是打击复杂项目依赖的好方法。使用多种语言/方言时,给定目标所需的依赖性存在很大差异。不,我不建议将其作为每个项目的最佳选择,但这确实为大型项目中的依赖管理提供了一些视角。


参考


注释

  • 这个问题最初是在模块介绍之前几年提出的。
  • 目前(Xcode 5.0),模块适用于C和ObjC,但不适用于C ++。

答案 2 :(得分:8)

我同意bbum。我对PCH文件的看法是它应该只包含#include#import语句。因此,如果您有一堆有用的高级宏,请按照bbum建议的文件Common.h#import来定义它们。

我通常更进一步使用PCH文件#import一个名为XXCategories.h的文件(其中XX是您使用的类命名前缀约定),其中包含{{1}我所有的UIKit和Foundation类别类别:#importNSString+XXAdditions.h等。

答案 3 :(得分:6)

创建一个头文件“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];