Here is a summary answer (not 100% correct). This subject is quite extensive to explain in a post, if you are not satisfied you will need to research to deepen the issue. I just want to give you a simple idea, I advise you to dig deeper.
But first, I’m gonna assume you don’t know C and give a brief explanation of how the code is turned into app.
We can say that there are 3 steps (actually there are more, but knowing these three is enough to get a good sense of the process):
1) Pre-compilation
This is when the code is prepared for compilation, when the directives #define
, #ifdef
, etc. are processed. That is, if we have a #define MyDef 3
, at the end of this step all sites of the code with MyDef
will have 3.
It’s also this step that generates macro reset, for example, if we have the files a.h
#define MyDef 3
and b.h
#define MyDef 4
When we use the MyDef
, its value will depend on the order in which we include the headers
.
#import "a.h"
#import "b.h"
// MyDef == 4
#import "b.h"
#import "a.h"
// MyDef == 3
2) Compilation
This is the gist of the whole process, which is why it is also called compilation to the three steps together, because this is the main.
It is this step that transforms code into machine language. This step results in binary files as executable code. Has the bytes that the processor will interpret while running to know what to do.
These partial binaries also have references to the other partial binaries and iOS libraries (as . framework).
3) Linking
This is the last step. This is when all partial binaries resulting from 2 are together in one executable.
This is also where resources are added to the final binary.
When using the directive @class
we are telling the compiler that the class exists and that there is no need to verify its existence by delegating this verification to the linking
.
For example:
@class XPTO;
@interface YPTO : NSObject
@property (strong, nonatomic) XPTO *xpto;
//...
@end
This .h
tell the compiler not to worry about XPTO that will be handled on linking
.
This has a problem, having no reference to the class, the compiler does not know how to use it. Therefore, in the .m
we add the #import
:
#import "YPTO.h"
#import "XPTO.h"
@implementation YPTO
- (void)yMethod
{
[xpto xMethod];
}
//...
@end
Without the #import
, compiler does not know the method reference xMethod
to be used when creating the partial binary of YPTO. This can be viewed as follows. Directive @interface
creates the references if the compiler does not read the @interface
does not know which references to use.
What happens is that the compiler (and also the compiler) runs through the YPTO.m
will i) read the YPTO.h
, ii) read the XPTO.h
and ii) read the @implementation YPTO
.
When to use @class
or #import
?
Uses the @class
when you don’t need the #import
.
Personally, I try to have the minimum of #import
s us .h
possible. Using the example of the XPTO and YPTO classes. Imagine that later we created a ZPTO class that uses YPTO but does not need FOO. By doing the #import "YPTO.h"
, compiler will not waste time reading the XPTO,h
nor the #import
s his.
Another advantage is that we reduce the possibility of having, for example,
a. h
#import "b.h"
b. h
#import "a.h"
Where when reading the a.h
, the compiler would read the b.h
, which in turn would make the compiler read the a.h
, b.h
, a.h
, ad infinitum.
I could erase the Imports of all my classes that refer to other classes and simply write @class
and then import them into implementation file?
I’m going to assume that when you say delete from the classes you mean .h
.
The answer seems to be "yes, you can". But there are two things to consider.
First of all, it’s not a good idea.
I know it seems to contradict what I answered to the other question, but what I said was that I personally try to have the minimum of #import
s us .h
possible.
Sometimes it’s better to have #import
s in the .h
.
Returning to the example of the XPTO and YPTO classes. Imagine that all YPTO methods receive and/or return XPTO instances. It’s very likely that whoever imports the YPTO.h
also want to import the XPTO.h
, saw that YTPO has a XPTO dependency relationship. In this case it will make sense that the #import "XPTO.h"
is in the YPTO.h
.
Second of all, you can’t.
Although it seems so, there are situations where this is not possible.
@class Super
@interface Class : Super
//...
@end
In this example, the compiler will not have a reference to the Super class and will not know how to solve the inheritance.
As an extra, I want to warn you that if you want to do something similar to @class
for protocols, you can do it with the @protocol
.
For example,
@protocol Delegate;
@interface Class : NSObject
@proprety (weak, nonatomic) id<Delegate> delegate;
//...
@end
However, it is not possible to do
@protocol Delegate;
@interface Class : NSObject <Delegate>
//...
@end
because the compiler will not have the protocol reference.