Cost of Including Header Files in Objective-C

2019-04-06 06:09发布

问题:

This may seem like a really stupid question, but what is the cost of including (actually, calling #import) a header file in Objective-C? I get tired of constantly including the same headers in various locations, so I decided to simply create a GlobalReferences.h file that includes several commonly-referenced headers.

Is there any appreciable cost for including references to other files if they aren't even used? My gut tells me "no" as it seems like the linker is just made aware of other files when using #import, but I wasn't sure if special considerations need to be taken for iPhone development, which is what my project concerns. Any thoughts?

回答1:

The linker knows nothing about #imported files. In fact, the Objective-C compiler knows nothing about them either, they are preprocessed out by the preprocessor. The preprocessor effectively inserts the contents of the headers into the point you've included them in your source file. The actual Objective-C compiler will then have to process extra function prototypes and class interface definitions even though they aren't being used. Though this is not usually a lengthy task, it can increase compile times. The resulting size and performance of your application should remain unaffected.

To see what the raw source code looks like (including all header files and expanded macros etc):

gcc -E your-source-file.m


回答2:

Importing/including more header files than you need will increase compile times. You can alleviate some of this pain with pre-compiled headers.



回答3:

The biggest drawback will be in compilation times. If all of your headers are imported in every source file, then the entire project will have to be rebuilt every time you make a change to a header file.



回答4:

I was under the impression that it wouldnt be too much of a hit: http://en.wikipedia.org/wiki/Objective-C#.23import



回答5:

what is the cost of including (actually, calling #import) a header file in Objective-C?

The compiler may run out to read these files unnecessarily. Once #imported, the additional files will need to be parsed, compiled, etc. for each translation (e.g. .m file) it is visible in -- making your build and link times much longer. 10 times longer is not surprising.

I get tired of constantly including the same headers in various locations, so I decided to simply create a GlobalReferences.h file that includes several commonly-referenced headers.

Typically, that's a very bad approach. The common problem is that whenever any of the files included by GlobalReferences.h is changed, your whole project and all in-between dependencies would need to be rebuilt, relinked, etc.

My preference is to separate programs into little libraries or packages where this interdependence exists (e.g. StoreKit.framework is a little package/library) -- but stuffing those libraries/frameworks/packages in headers solves nothing. Also, forward declarations and storing your data in the class continuation or @implementation can significantly reduce dependencies (because you can localize the inclusion of a library/header to only the necessary translations).

Lastly, cleaning up after lazy includes is very time consuming, especially when there are many and you've waited until your project's build times are unbearably slow. Basically, you have to go back and pick apart unnecessary dependencies, rebuild, repeat (for days).

Is there any appreciable cost for including references to other files if they aren't even used?

Absolutely. The larger your projects grow, the worse lazy inclusion becomes. A few lazy includes in a large project could add tens or hundreds of thousands of lines to most of your compiled files, and can trigger frequent recompilation of many sources. This adds a significant amount of complexity to the build process -- CPU demands go way up, RAM usage goes way up, disk IO goes way up… and again, this becomes a bigger problem as your codebases/projects increase in complexity.



回答6:

Go ahead and do it. Unless the headers you're including are massive and you're not using precompiled headers, you shouldn't see any difference. As others have said, #import is a preprocessor directive. This has no runtime consequence and in many cases no significant compile time consequence.