Import in header file vs. import in source file - objective-c

What is the general rule for using an #import in a header file, as opposed to using an #import in a source file?

By #importing a header you create a dependency. As a 'general rule' it's good to minimise dependencies.
There's more to it than just placement of #imports. Few remarks:
Put as little definitions/properties/imports/... in your headers as possible; ergo, move as much as possible to the source file. A header is the public API of your module/class, you want to keep it as clean/to-the-point as possible. This avoids all kinds of dependencies that are actually not necessary.
It's often sufficient to add #class ClassYouNeed; (typically just below the #imports you do really need) instead of #import "ClassYouNeed.h". This is when just that class is used as a type, and no other definitions from ClassYouNeed.h. Typically you'd add #class ClassYouNeed; in the header and then do the full #import ClassYouNeed.h in the source file, because in the source file you typically need more than just the class/type. The compiler will sort things out for you.

In a header file, import only headers which are needed for the header file itself (the interface) and not for the implementation. Within the source file (the implementation) import the respective header file and any other headers which are needed only for the implementation.
This way, when the outside world includes your header, it will only expose what's relevant to its interface and not what's relevant to the implementation.

Related

Need To Import Sub-Framework Header File for JNI in Objective-c

The JavaVM framework contains a sub-framework, JavaNativeFoundation framework. This sub-framework contains a header file, JNFRunLoop.h, that I need.
According to Apple documentation:
#import <Framework_name/Header_filename.h>
In both cases, Framework_name is the name of the framework and
Header_filename is the name of a header file in that framework or in
one of its subframeworks.
#import <JavaVM/JNFRunLoop.h> does not work (JavaVM/JNFRunLoop.h file not found).
I tried adding the sub-framework headers to the header search path, and while this allows me to import it, it gives a compile-time error which is mentioned in the documentation:
The umbrella header files and the subframework header files contain
preprocessor variables and checks to guard against the inclusion of
subframework header files.
I ultimately need to do this:
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:block];
which won't work until I can import that header file. Any ideas?
The authors of the library have put that guard on purpose. Are you sure you are doing the right thing?
If the library allows modifications the right way would be to take it and adapt it to your needs.
If you need a quick and dirty way to call that method, you can try to declare it inside your ".m" file like so:
#interface JNFRunLoop
+ (void)performOnMainThreadWaiting:(BOOL)w withBlock:(void (^)(void))b;
#end
(it must match to how it is declared in JNFRunLoop.h in terms of name and parameter types)
After this declaration it becomes available for calling. Note that this won't work, if the library requires some special initialization steps, or if that function name is mangled in their binary or not present their.

How to import a lot files at once?

Say I have a ton of small classes that I want to import all at once, is there a way to define a file that is literally just a list of imports and then only import that one file instead of having a long list of imports for each class?
Your suggestion will work fine: you can create a header file, and put #import "..." directives in it. Then you can include that header in all your files as needed.
Xcode provides an even better solution - the file called Prefix.pch. Instead of creating your own header, put the #import directives there. The result would be that all your files will implicitly include the files that you import in Prefix.pch - you wouldn't even have to import them.

I need to create separate file for all the constants of my project

In my project I have a requirement to create separate file for all constants that i am using in separate classes in the same project.
I seen some examples but they are saying about creating in '.h' file and again they are implementing them in '.m' files. But i need only '.h'file to create all constants and i have to use all those constants by importing that '.h' file in every class of my project.
ADD a new file.
Right click on the file inspector
choose New File
The pop up window select ios>C and C++>HeaderFile[Figure]
Give name Constants
Add #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);
You can create .h file and use #define to create constants and then include your file to prefix file of your project. Though I prefer to use extern constants which you declare in .h file and define in .m file. This help to track possible warnings in your code at compilation time.
You've pretty much answered your own question, to the point where I'm not sure exactly what you're asking - you can just create a header file (.h) with your constants, and import it into your other classes. You don't need to create a corresponding implementation (.m) file. If you're using your constants throughout your code you could import them in your prefix header and have them automatically available.

In Objective-C, do I need to import every h file to see my object hierarchy?

I've created an 3 objects, and chained them together:
Questionnaire object - which contains a
NextQuestion object - which contains an
Answer object - which has an text property.
In a ViewController, I want to be able to call:
NSString *thisAnswerText = Questionnaire.nextQuestion.answer.text;
However, to do this, I have to import all three files into my .m file
#import "Questionnaire.h"
#import "Question.h"
#import "Answer.h"
Is it necessary to import each of the objects that I use in each .m file? Or is there something I can do which means I only need to import the top level item and all it's children are automatically referenced?
NB. I know that I can add all three to the Prefix.pch file, but I was wondering if I'm missing some trick to Objective-C which allows me to declare one item and it's child objects become imported automatically?
THANK YOU!
When you import a .h file any imports within the .h file are also available. You may need to clean and rebuild but they should be available. So in your case no, you should be able to get away with importing the Questionaire.h only.
Also if you're app depends on those custom classes and they will be used all over the place, it can be a good idea to import them in your .pch file and they will be precompiled for all your classes.
Is it necessary to import each of the objects that I use in each .m file?
Not in all cases, but if you message an object, you should ensure the compiler sees its declaration -- just because ObjC is a very dynamic language.
Or is there something I can do which means I only need to import the top level item and all it's children are automatically referenced?
Yes, you could add an #import in any header (of course, the must be compatible with the translation). However, adding #imports should be minimized because #importing the world will increase your build times and introduce a bunch of dependency.
In the public header files for your interfaces, you should forward-declare as much as possible and only #import what is really needed. This will help to keep build times down. In your implementation files you can import anything you need.
Sometimes for usability's sake, you may which to collect multiple headers into a single "MyFramework.h" file so that you don't have to add 5 imports everytime you use a class. You should be careful with this however, because it can increase build times if the header is imported in many places.
You may also want to think about adding common imports to your prefix header (.pch) which can be precompiled by Xcode to improve build times a little.

Importing into .h versus .m

Is there a difference between importing something (e.g. #import "JSON.h") into the header file versus the implementation file?
If you #import it in the header, then everything including that header gets it. You may find that useful, in that you don't have to #import it again in other places, but my preference is to #import things only where necessary, to minimize dependencies and make builds faster.
I think if you do it in the header file, you save your self some trouble later on in case you reference a class which is defined in the imported file.
In other words, if you import "JSON.h" in the header file, and there's a JSON class (hypothetically) that you will use in your header file (in the interface), then it would save you from having to do the #class directive at the top. Then your implementation file will also be fine since it would import the header file, which itself imported the "JSON.h" file
Basically I think it would be neater and would be more like objective-c if you import the required files in the interface file (.h). As you've probably noticed, interface files are usually short and concise, allowing you to get a quick glance at what a certain class is about and what it does. If you import your files there, you can also see what files/classes it relies on more easily, saving the implementation file (.m) for the actual 'meat'.