Should I put all header file into Prefix.pch? - objective-c

Is it recommended to refer to all my header file in Prefix.pch, and then I do not have to type #import headers during development?

I wouldn't recommend this.
The main reason is, header files can change in the course of your development. If you change one header, it will cause the pch to dirty, have to be rebuilt, and now your entire project will rebuild. That's quite time-consuming, and works counter to the whole reason for pch files.
Same thing if you create a new header file, add it to the pch, and now that triggers and entire rebuild.
But there's no single answer here. You may have a 3rd party library that will never (or rarely) change, is quite header-intensive, and so precompiling it may be a way to reduce build times. Experiment and see.

Pre-compiled header files were brought to serve one purpose: to make compiling faster. It is compiled and stored in cache, and automatically included in every source file during the compilation time. Its like each source file does,
#import "Prefix.h"
This can be handy for project-wide #defines. (FYI, #defines are a code smell)
Xcode quotes:
Precompiling the prefix header will be most effective if the contents
of the prefix header or any file it includes change rarely. If the
contents of the prefix header or any file it includes change
frequently, there may be a negative impact to overall build time.
More clear explanation is here
Please keep this in mind when you #import source file header in .pch. As a tip, you can use Prefix.h for #import of constants and utility source files.

From a standards perspective, your includes should be as minimal as possible. Indeed, you shouldn't include anything you don't require for compilation into any file. So, in each of your .h files you should primarily include the superclass and use #class for all other references, then include only in your .m files. This gives the clearest information about the requirements of each class / file and minimises circularity issues.

You should add header file to Prefix.pch just if you need that file/class in most of your other classes. If you need the header file just in one or two other classes it's not point to add it to .pch because it will takes more time for compiler to compile the files and it will happen every time you want to run your project.

I add all the headers to Prefix.pch, and I have to claim life is much easier since that time. I just do not have to import always headers, believe me, life is much easier. :-)

Related

Objective-C header file not found (AFNetworking.h) [duplicate]

This question already has answers here:
AFNetworking.h file not found
(5 answers)
Closed 1 year ago.
#import <AFNetworking/AFNetworking.h>
I imported AFNetworking.h file to .m file but an error occurred like this:
'AFNetworking/AFNetworking.h' file not found
I deleted pods folder and Podfile.lock, and reinstalled Podfile but didn't solved. What should I do? (I opened the workspace file.)
Linking !== Copying.
there is C style #include ... and Objective-C style #import ...
both work almost the same..
where #import reads the header but does not include again if done once. As this can and does fail sometime (usually because mixing C,C++,Objc,Objc++ in different dialects) we often use #define rules to make sure the enclosed code is read once for sure and not again, which in turn works also when code is included and declared with #include. It would be included but not compiled twice.
#ifndef SOME_HumanReadableFlag_h
#define SOME_HumanReadableFlag_h
// ... your header code here..
#interface XyzObject : FromInheritedClass
#end
#endif
Now why does it matter?
It might happen that a #define rule enclosing the header files content hides the header from the viewpoint of other classes.. This can & does happen often when classes are not properly written with the end developers structure in mind. It might work on the workbench of the developer but not for everyone else implementing it.
Your error clearly tells "File not found .."
So first see what both import/include rules differentiate in general
#import <LibFrameworkName/LibFrameworkName.h>
means you have to link the framework or library, even if you developed one on your own in that project. The rule is relative to your project, LibFrameworkName is a Framework/Lib. Where if found somewhere #include <LibFrameworkName/LibFrameworkName.h> is not correct unless you want to c-style include this framework header into your binarys header, 2) tells you a bit about why..
#import "LibFrameworkName/LibFrameworkName.h"
means you have to copy/offer this header into your project with a subfolder with name LibFrameworkName. Once somewhere declared properly Xcode might find and apply the headers even if declared with the wrong rule later on in that specific class, you should also get a warning in the IDE then. In case of AFNetworking you dont want to copy System SDK Frameworks into your project, also not into third party frameworks unless you know what you do. This rule is relative to the files place in project structure, meaning here it would try to look out for some folder with name LibFrameworkName below the file that carries this rule.
what it says: because the Framework is not linked, the compiler tries to find it with the given name ignoring < & > so as if it where like 2) a file with that folder name, then will not find it and throws the error or warning.
To force the precompiler to parse thru some specific folders we use sometime the header search path to explicit tell where to find it. Widely used and mostly troublesome because it also hides wrongly defined rules to the developer as Xcode skips the still existing wrong import rules in code assuming it knows this headers already. Or it throws warnings while everything is actually fine. Other developers experience trouble then, the file structure and header list don't match at all. So keep in mind, when you can avoid making use of header search path lists, go for it. It also will and should not fix your issue.
'<AFNetworking/AFNetworking.h>' File not found means a Framework module is not known to your project. This header is part of a Framework.
Solution: You have to go to your Projects Settings and scroll down to Frameworks and Libraries, hit [+] below this list. It should open the dialog presenting all SDK from your choosen Project Target and all known Pods or known frameworks of your own project when you developed some. Search for the Framework or Lib by name, click it, hit "Add".. done..
From there - there are some options to get used to it..
Because Linking does not mean Copying into your Resources at compile time by default. Usually Xcode knows it does not have to copy System SDK into a projects Framework Folder, all macUsers have those Frameworks preinstalled on their system of course in the right version.. Linking against some specific folder like ${SOMEFLAGWHEREEVERTHISPOINTSTO}/AFNetworking/AFNetworking.framework/Headers is actually wrong unless someone wanted to overrule the systems framework header and maybe also binary.
So AFNetworking should not appear under Build Phases > Copy Bundle Ressources list but after the process above is done it will appear under Link Binary with Libraries, it might also be placed in Dependencies when Xcode needs to know for some Library/Framework it must have this to compile. Last mentioned option is because you could have a framework that adapts at runtime when some framework is missing or not available. So this Entry helps Xcode to figure out in which sorting it has to compile your stuff.
finding ${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers in Header Search Paths there must be something wrong i guess.. because the framework is very likely not copied into the Pods folder. It should be relative to your SDKs folder that come with Xcode. The Linking process told above should fix that and you can erase that entry from your header search path then.

If UIKit is imported in the PCH file, then why is it imported again in each file?

If #import <UIKit/UIKit.h> and #import <Foundation/Foundation.h> are both found in our `ProjectName.pch' file, making them globally imported, why are they automatically added to the header file when Xcode creates a new class?
The .pch is there as a compile time optimisation, personally I recommend making sure that classes can still build without a pch (so still import into h/m's manually), so that it can A) build without and B) so that if you re-use code, you can easily see its dependencies.
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.
Only Apple knows for sure.
Best guess: Apple can not be sure that the imports are in the pch file for all projects or that there is even a pch file. This by having these implicit imports compiling can be guaranteed.

Where is the implementation part of frameworks' header files (objective-C)?

I am learning Objective-C, but can't understand one thing with the frameworks. Each framework in objective-C contains header files which contain only #interface part. That means that header files only declare difference methods and do not implement them. Is this implementation part hidden in the frameworks or something, because I can't get how it works.
Thank you in advance for your answers!
Is this implementation part hidden in the frameworks or something
Well, sort of. It's compiled (the actual source code is not present neither in the SDK nor in the OS) and only the binary executable code is contained within the dynamic library that resides inside the framework.
It is still possible to use them (i. e. link against them), obviously (see this for an explanation), but you cannot edit the source code. In theory, you could try binpatching them (i. e. disassembling, analyzing and editing the executable file using a hex editor or something), but that's neither recommended (you can screw up your entire system if you do one slight thing wrong), nor easy.

lesscss import and watch

I have two files:
black.less
/* imports */
#import "elements.less";
#import "crush.less";
#import "tree.less";
I'm using the less watch functionality by adding:
less.watch();
Sure enough I can see the traffic getting black.less. Black.less hasn't changed though so any change in any of the files being imported is not counted as a change and the style is not updated.
If I however touch black.less the style updates as it should.
Is there a way to automatically update regardless of if it's an imported file or the actual less file being added to the page i.e. so that I only have to change let's say tree.less.
/K
I use Grunt and the grunt-contrib-less plugin to watch all of my less files and compile them into CSS as they change.
Then I use live.js in the browser to watch the CSS files.
The advantage to doing it this way is that I can do the same thing with my HTML and JS files, as well as run tests, lint my JS files, etc.
Remy Sharp recently wrote a post about how newer versions of Chrome support the ability to save files that you edit in the dev tools back to the file system.
He advocates Never having to leave devtools. Just do your edits right in the browser. The advantage to this solution for you is that you could continue to use the client-side Less compiler.
(I still like my robust text editors and command-line too much to ditch them entirely, but thought this answer would likely appeal to at least a few people who arrived at this question.)
Here's another quick way.
watch -n 1 touch black.less
This may be too late for op, but I had the same question and maybe others have it too.
less-watch-compiler will watch a directory (and sub-directories) for changes and compile any less code to a destination folder. The cool bit is that you can specify the main file and only the main file will be compiled when any file in the source directory is changed.
Usage:
less-watch-compiler [options] <source_dir> <destination_dir> [main-file]

When should I import a header to Prefix.pch?

I've heard importing a header to Prefix.pch can improve performance as it will load the header once, instead of on each instance. So when is a header imported enough times in a project to warrant being included in the Prefix.pch? A dozen times? Several times? Just twice?
I typically add a header to Prefix.pch if it is being #imported into more than 3 classes. I don't think there's a rule of thumb - it depends on your own standards for what you consider clutter, elegance, how globally the code is used etc. For example, most of my projects have a Utilities.h and Utilities.m where I declare helper functions used in many places. I always add Utilities.h to my .pch.
I tend to avoid the temptation of chucking too much stuff in the .pch. In particular, it obfuscates the dependencies in your code. Suppose you want to see where your code is using AFNetworking lib (for example): You search for the #import statements, and then see that the .pch file imports it, which tells you... nothing.
If when using a module/lib you usually import a number of related header files you can create a new header file that just imports the glob of related headers and then import that instead.