So many developers are adding various convenience macros to the Prefix.pch. But my question is what is that Prefix.pch file.
If i remove that Prefix.pch file from my Xcode, then will my application run? Or will it show any error? Or will it crash during build?
How can i run my application without Prefix.pch file
Precompiled header.
What is it?
A Prefix.pch is a precompiled header. Precompiled headers were invented to make compiling faster. Rather than parsing the same header files over and over, these files get parsed once, ahead of time.
Xcode
In Xcode, you add imports of the header files you want in a “prefix header,” and enabling Precompile Prefix Header so they get precompiled. But the idea behind a prefix header is different from precompiling.
A prefix header is implicitly included at the start of every source file. It’s like each source file adds
#import "Prefix.pch"
at the top of the file, before anything else.
Removing it.
You can remove the precompiled header. This question has been already answered in thread I'm linking below. It contains all the information you need as well as useful comments.
Is it OK to remove Prefix.pch file from the Xcode project?
What is Prefix.pch file?
A .pch is a Pre-Compiled Header.
In the C and C++ programming languages, a header file is a file whose text may be automatically included in another source file by the C preprocessor, usually specified by the use of compiler directives in the source file.
Prefix headers are compiled and stored in a cache, and then automatically included in every file during compilation. This can speed up compilation, and lets you include a file without adding an import statement to every file using it. They are not required, and actually slow compilation whenever you change them.
Yes, you can compile and run the project without .pch file
In Xcode, go to your target's build settings (Command-Option-E, build tab) and uncheck Precompile Prefix Header (GCC_PRECOMPILE_PREFIX_HEADER). You can also remove the value of the Prefix Header setting if you wish.
Also note that,
Don't put macros in a.pch file! A .pch file is, by definition, a project specific precompiled header. It really shouldn't be used beyond the context of the project and it really shouldn't contain anything but #includes and #imports.
If you have some macros and such that you want to share between headers, then stick 'em in a header file of their own — Common.h or whatever — and #include that at the beginning of the .pch
Prefix headers are compiled and stored in a cache, and then automatically included in every file during compilation. This can speed up compilation, and lets you include a file without adding an import statement to every file using it. They are not required, and actually slow compilation whenever you change them.
Generally .pch file naming formation is yourProjectName-Prefix.pch
Prefix Headers and Precompiled Headers (.pch)
History:
[#include -> #import] -> Precompiled Headers .pch -> [#import Module(ObjC);] -> [import Module(Swift)]
Precompiled Headers - prefix.pch
To create new .pch file
File -> New -> File... -> PCH File
PrefixHeader.pch sample:
#ifndef PrefixHeader_pch
#define PrefixHeader_pch
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
From Xcode 6 you should set .pch manually. Previously it was called <product_name>-Prefix.pch
Xcode:
Prefix Header(GCC_PREFIX_HEADER) - path to .pch. Adds all content from .pch to all source files
SomeFile1.h
//You can skip this section. It will be compiled
//#import <UIKit/UIKit.h>
//#import <Foundation/Foundation.h>
//implicitly next line is used
#import "PrefixHeader.pch"
Precompile Prefix Header(GCC_PRECOMPILE_PREFIX_HEADER) - When Yes then Prefix headers from GCC_PREFIX_HEADER will be used once* to generate precompiled sources and will be stored in a cache which speeds up a build time
//path to cached precompiled headers
/<some_path>/DerivedData/ExperiementsModuleSwift-dsetoksxykdmgvczgtnmaqmjwhzk/Build/Intermediates.noindex/PrecompiledHeaders/SharedPrecompiledHeaders/14385052922615550324
//e.g
/Users/alex/Library/Developer/Xcode/DerivedData/ExperiementsModuleSwift-dsetoksxykdmgvczgtnmaqmjwhzk/Build/Intermediates.noindex/PrecompiledHeaders/SharedPrecompiledHeaders/14385052922615550324
#import vs .pch
This feature improves build time(comparing with #include/#import) because precompiles a prefix headers(global). When some content of prefix headers is changed it means that Compiles must recompile that again. that is why you should use stable(not often changeable) prefix headers here or you dont't see build time improvement. Also you should support it
Related
ProjectName-Prefix.pch is Missing in Xcode 6.
We can create .h file and use #define to create constants and then include this file to prefix file of our project before Xcode 6.
Sample constant.h file
#define OK #"OK"
Go to View Controller include file in header #import "Constants.h"
OR Define in pch file ,so that all View controllers can access the file
In viewDidLoad
NSLog(#"%#",OK);
My question is
where to include my constant.h file so can be access the file from all view controllers like we did using .pch file?
EDIT:
My question is replacement of .pch file ? As if apple remove it from Xcode their must be some alternate to achieve this goal without adding .pch and include in every single file to be used
You answered your question yourself. Here
We can create .h file and use #define to create constants and then include this file to prefix file of our project before Xcode 6.
You include the Common.h file inside the pch file. And you dont have to #import anything, as PCH file is available in all classes, and any import inside the PCH file is also available in all classes. Hence PCH files are termed as Pre-Compiled Header files.
You can configure a pch file in Build Settings->Prefix Header. Type in the path to the pch file or a .h file relative to the xcodeproj file.
Yes You can create header file for Xcode. I am sure pch is best way to used whole application. You can import constant file on pch and used in whole application.
Why isn't ProjectName-Prefix.pch created automatically in Xcode 6 ?
Is the precompile header no longer needed ?
Where should I write the code that was in ProjectName-Prefix.pch before ?
Without the question if it is proper or not, you can add PCH file manually:
Add new PCH file to the project: New file > Other > PCH file.
At the Target's Build Settings option, set the value of Prefix Header to your PCH file name, with the project name as prefix (i.e. for project named TestProject and PCH file named MyPrefixHeaderFile, add the value TestProject/MyPrefixHeaderFile.pch to the plist).
TIP: You can use things like $(SRCROOT) or $(PROJECT_DIR) to get to the path of where you put the .pch in the project.
At the Target's Build Settings option, set the value of Precompile Prefix Header to YES.
I suspect because of modules, which remove the need for the #import <Cocoa/Cocoa.h>.
As to where to put code that you would put in a prefix header, there is no code you should put in a prefix header. Put your imports into the files that need them. Put your definitions into their own files. Put your macros...nowhere. Stop writing macros unless there is no other way (such as when you need __FILE__). If you do need macros, put them in a header and include it.
The prefix header was necessary for things that are huge and used by nearly everything in the whole system (like Foundation.h). If you have something that huge and ubiquitous, you should rethink your architecture. Prefix headers make code reuse hard, and introduce subtle build problems if any of the files listed can change. Avoid them until you have a serious build time problem that you can demonstrate is dramatically improved with a prefix header.
In that case you can create one and pass it into clang, but it's incredibly rare that it's a good idea.
EDIT: To your specific question about a HUD you use in all your view controllers, yes, you should absolutely import it into every view controller that actually uses it. This makes the dependencies clear. When you reuse your view controller in a new project (which is common if you build your controllers well), you will immediately know what it requires. This is especially important for categories, which can make code very hard to reuse if they're implicit.
The PCH file isn't there to get rid of listing dependencies. You should still import UIKit.h or Foundation.h as needed, as the Xcode templates do. The reason for the PCH is to improve build times when dealing with really massive headers (like in UIKit).
You need to create own PCH file
Add New file -> Other-> PCH file
Then add the path of this PCH file to your build setting->prefix header->path
($(SRCROOT)/filename.pch)
I'll show you with a pic!
Add a new File
Go to Project/Build Setting/APPl LLVM 6.0-Language
To add .pch file-
1) Add new .pch file to your project->New file->other->PCH file
2) Goto your project's build setting.
3) Search "prefix header". You can find that under Apple LLVM.
4) Paste this in the field $(SRCROOT)/yourPrefixHeaderFileName.pch
5) Clean and build the project.
That's it!!!
If you decide to add a .pch file manually and you want to use Objective-C just like before xCode 6 you will also have to import UIKit and Foundation frameworks in the .pch file. Otherwise you will have to import these frameworks manually in each header file. You can add the following code anyway as it tests for the language used:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
Use :
$(PROJECT_DIR)/Project name/PrefixHeader.pch
For add new PCH file follow bellow steps :
(1) Add New fiew - Select iOS - Other and PCH File
(2) add path of this PCH file to your Project - BuildSetting - Apple LLVM 6.0 Language
Add Set Prefix Header Path YourApplicationName(root-path)/filename.pch
I added two files to a Xcode 5.1 vanilla single view project:
table.h
struct group {
int size;
};
table.c
#include "table.h"
and got this error:
Semantic issue
table.h:2:8: Redefinition of 'group'
"Previous definition" is:
iOS 7.1 > usr/include > grp.h
I am wondering why this grp.h is automatically included in my project. How can I not include it?
grp.h is one of the standard Unix-level files which defines some of the basic data structures; in this case, struct group is what gets returned by low-level C functions that deal with user permissions.
As for the question of why it's included in your project: When you create a new project in Xcode, it creates an include file that implicitly gets included in every .m or .c file in your project. In the project I just created to try this out, it's in the file browser in a group called Supporting Files, named something like [project]-Prefix.pch. Mine has the following contents:
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
That second to last line, #import <Foundation/Foundation.h>, then includes all the built-in Objective-C objects like NSObject, NSArray - and a bunch of things that work with the filesystem, and therefore need to be able to deal with permissions and group membership. One of those is then including grp.h.
So, back to your question - you can change your .pch file to not include Foundation/Foundation.h, and then manually include it wherever you need it.
But that will end up slowing down all your builds. The .pch file here is special; Xcode compiles it once and saves it in a binary format, so it doesn't have to parse the many thousands of lines of C code it expands to for every file you build.
My advice? Name your structure something else.
Normally of course it would be easier to change the naming of your struct, but as it comes from another library, here is my solution for you.
Turns out that if you allow your .pch file to include any of header files from iOS 7.1 > /usr/include then it will reference (include?) many more, including grp.h which causes the problem in your project.
So for example, if your .pch files contains this:
#import <Availability.h>
Then grp.h will cause the conflict.
If you comment out this line (and don't include any other headers from "iOS 7.1 > usr/include") then your project will compile.
As a test you can comment out <Availability.h> and add #import <cpio.h> and the result will be the same (although cpio.h is very small and don't reference any other header files).
I am not that good at understanding internals of compilation, so I can't explain why this happens but I traced down the issue to this file:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include/module.map which seems to group together various Darwin header files.
Both iOS 7.0 and iOS 7.1 have this file while iOS 6.0 doesn't (which may explain why the same code worked on earlier iOS versions).
The good news is that although you need to remove /usr/include headers from your *.pch file, you can still include them in files where you actually need them and it won't break the compilation. That's probably because although the grp.h will eventually be included in those files, it won't be included in your table.c
grp.h has already declared a struct named 'group',
so you just need to rename your 'group' struct and everything will be ok.
(for example 'my_group')
Default file:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#end
My understanding is pre-compiled headers are included in every file. Why doesn't this import just go into the pre-compiled headers?
There is no guarantee that every project have a .pch file that import Foundation.h so Xcode need to generate it to make sure new files always compile.
Also some people think it is good style to include header even it is already included in .pch file. Because you know exactly what headers are needed by this file. It also allow people to disable prefix header if needed.
My Xcode 5 doesn't appear to be including it in every class (it is included in the .pch file). I agree with you that this makes more sense than including it everywhere. The answer to your question is probably "an oversight on Apple's part" :)
I am just wondering, is it good practice to include commonly/mostly used header files in .pch file?
e.g Most of files required below headers
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
So instead of each file should have, is it good practice to add those in .pch file?
.pch file
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <MostlyUsed.h>
#endif
I found some disadvantages of this,
1) Dependancies get hidden.
2) Source files can not be copied directly.
It will be great if you guys provide some inputs on this.
Thanks
Yes you can do it.
Even it reduces compile time.
An Extract from In Objective-C, importing same headers in every class make compile time longer?
In general, newly-generated iOS projects come with this functionality,
which is called a precompiled header or prefix header, and is a file
that has the extension .pch.
You can throw all the headers you want in there and Xcode will
pre-compile it before it builds anything else, and use it to compile
the other compilation units in your project (e.g. .m files).
Using a precompiled header may or may not increase compile time; in
general, it reduces compile time, as long as you have a lot of common
headers and/or a lot of source files.
However, it's not necessarily good practice to treat the pre-compiled
header like a big dumping ground, as your compilation units can form
implicit dependencies on all sorts of stuff when you may want to
enforce loose coupling between components.
It is certainly a good practice as it reduces compile time and code is lot more manageable by doing so.