Importing into .h versus .m - objective-c

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'.

Related

Importing modulename-Swift.h file to ObjC .h file

Is it possible to import the modulename-Swift.h file to another .h file, so that the test target also would compile?
Currently, I was importing the modulename-Swift.h in the one of the headers of the app's target, however, the test target was not able to compile.
When I moved the import statement to the .m file instead, I was able to compile both, the app and the tests.
However, I have to resort to a forward protocol declaration in order to resolve this issue - the modulename-Swift.h file contains a protocol.
So, the question is whether I can import that file in .h file at all?
No, you can't import modulename-Swift.h in a .h file. You'll need to create forward declarations (adding #protocol Something; to your .h) and import the Swift module in the .m file.
Another way to work around this is to declare the protocol conformance in a category in the .m file. More details can be found in this StackOverflow answer:
https://stackoverflow.com/a/27626493/3208043

Nested #import statements: how to hide nested ones?

I have the following project structure:
Main.h
Son1.h
Son2.h
They're not related (no father/son relationships), just two imports, like in Main.h I have:
#import Son1.h
#import Son2.h
If, from another file I write
#import Main.h
I will see all the methods/properties of Main.h (and that's ok) but I will also see the methods of Son1.h and Son2.h.
How can I prevent this?
It's important to understand what #import (and the C version: #include) do.
Compilation of C programs conceptually have 3 steps:
Preprocessing
Compiling
Linking
The directives beginning with # are acted on by the preprocessor (it doesn't matter at all whether this is a separate binary or part of the compiler). Both of these statements cause the contents of the named file to inserted into the importing (or including) file at the point where the directive is found. This is completely language-agnostic. The imported file can have anything in it. You can import a JPG, if you want (but good luck compiling!).
In your example, by importing Son1.h and Son2.h in Main.h, you are creating, from the compiler's perspective, a single file with the contents of Son1.h followed by the contents of Son2.h followed by whatever is in Main.h itself. At this level, the idea of hiding content doesn't make sense. You explicitly asked the preprocessor to put those contents there. It doesn't know anything about the text it's inserting, so it can't follow any kind of Objective-C directive, even if such existed.
The comments are getting to another point. Importing in a .h should be kept to an absolute minimum. The most common reasons to import are for class and protocol type definitions, and Objective-C allows you to forward declare both of these precisely to avoid otherwise necessary imports.
If you have something like:
#interface MyClass : NSObject
#property(nonatomic, strong) MyOtherClass *myOtherClass;
#end
You normally would have to #import "MyOtherClass.h". However, with forward declarations, you can do this instead:
#class MyOtherClass;
And move the #import to the implementation file, which is generally hidden from other files.

Import in header file vs. import in source file

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.

Where to #import on Objective-C

My project has been increasing in size and I'm a little confused about where should I #import header files.
There are 3 main locations where I can import headers:
The .pch file (prefix)
The .h file (header)
the .m file (implementation)
I don't care if the compiler takes more time to compile the files, all I care is that the end product is as fast as possible and uses the least amount of memory.
So, my questions are:
If most files need a specific header, is it ok to add it to the .pch file, or is it more efficient to add it to just the required files?
Should imports be done in the .h or .m file? I know I must add it to the .h file if i'm going to declare it there, but if I don't need to declare it in the .h file is there a problem of leaving the import there?
No, it is not ok to include it into the .pch file. This file is precompiled to every module in the project. Read about it here.
Read this question and answer.
Put your imports in your .m whenever you can. If you are using a class in your .h use #class to forward the declaration, then #import in your .m. The only time you should import in your .h are protocols that you implement or superclasses.

Objective-C: Importing headers in .h or .m?

I'm new to objective-c and would like to know the best practice for importing some external headers that I use in my class.
Should I be storing the #import "classB.h" in my own classes .h file or in the .m file?
What's the difference?
Thanks!
It is proper practice to put a forward class declaration (#class classB;) in the header and #import "classB.h in the .m
A forward class declaration, like #class classB; lets the compiler know it should expect the class later on, and it shouldn't complain about it at the moment.
To avoid circular references, only #import a header file in another class's header file if it's inheriting from that class. Otherwise, use #class ClassName to declare the class type if you need it in your header file, and #import it in the implementation file.
To the compiler, it really doesn't matter. You could just throw forward declarations in your .h and then wait to #import until your .m file. See this post on SO for more info on this.
From a clean-code prospective, some may argue that putting the imports in your implementation file keeps the details closer to where they are needed (see that link above as well; the people there reference this idea).
It's recommended that you import other header files in your header file. That way you can use the class in both the header and the implementation files (because the implementation file (.m) imports its associated header file).
If you want to know when to import files and when to use forward-class declaration, you can go here. ;-)