#class vs #import - objective-c

What is the difference when using #class or #import in objective-c?
I have seen various tutorials and only a few use #class while most of the others use #import.

#class doesn't import the file, it just says to the compiler "This class exists even though you don't know about it, don't warn me if I use it". #import actually imports the file so you can use all the methods and instance variables. #class is used to save time compiling (importing the whole file makes the compile take more time). You can use #import if you want, it will just take longer for your project to build.

See Defining a Class, especially Referring to Other Classes.

Related

how can i specify the UIApplicationDelegate protocol, and only the UIApplicationDelegate protocol?

Xcode generated this header file based on a template:
// this file is XYZAppDelegate.h
#import <UIKit/UIKit.h>
#interface XYZAppDelegate : UIResponder <UIApplicationDelegate>
....
#end
For the compiler to figure-out what UIApplicationDelegate is, this is how it works?
(1) the entire UIKit framework (UIKit.h) has been imported.
(2) UIApplication.h is one, of many, header files specified in UIKit.h.
(3) the UIApplicationDelegate protocol is then specified in UIApplication.h.
Just for the sake of my understanding, could i write a:
#interface XYZAppDelegate:UIResponder <direct-reference-to-protocol>
maybe, something like:
#interface XYZAppDelegate:UIResponder <UIKit.UIApplication.UIApplicationDelegate>
To specify a protocol on a class it needs to be known by the compiler. The one and only way to do that is by specifying
#protocol MyProtocol
...
#end
This is also the case for classes, categories, anything.
The compiler, like any C compiler, processes file by file. It can and will not remember anything it saw between runs. This means, to be able to know what MyProtocol is, the compiler must be provided with the protocol definition like above in the very same file.
Because it would be very annoying to always specify things a million times, the C people have figured out decades ago, that it would be great if there would be preprocessor directives that insert a specific file at the place where the directive is. This is when #include was born.
#import is basically the same as #include, only that it also checks if the file has been included before and doesn't do it multiple times as #include would do. Both just take the file and pretend the whole content of that file would be at the place of the directive - nothing more.
As neither C nor Objective-C have framework level namespacing, every symbol that is known to the compiler can and must be simply used by specifying its name. Things like the . syntax for namespace that you may know from Java (like System.out.println()) or other programming languages don't exist.
You maybe want to check this out What is the difference between #import and #include in Objective-C?
Sure, you can
#import <UIKit/UIApplication.h>
#import <UIKit/UIResponder.h>
instead of
#import <UIKit/UIKit.h>
However, i can see some disadvantages this way. What if Apple will move UIApplicationDelegate protocol declaration to another header upon time? What if you'll need in some of your files 10 UIKit classes? Would you write
#import <UIKit/UIView.h>
#import <UIKit/UIScrollView.h>
#import <UIKit/UIButton.h>
...
#import <UIKit/header_over_9kth.h>
However, you can try optimizing your imports and post compiling time reports here. It would be interesting if you'll achieve more performance with such optimisations

#import is doubling up interface definitions and causing error

I have two classes: RequisitionGetdetails and RequisitionRelease. Both #import USAdditions.h in the .m file
Now in class file: ReqDetailViewController.m I #import RequisitionGetdetails.h and RequisitionRelease.h and when I compile I get duplicate interface definition for all objects defined in USAdditions.h
I only use #import. I do not have #include anywhere in my code. I thought #import was supposed to handle duplicate definitions like this.
If I comment out #import RequisitionRelease.h the duplicate error goes away which tells me the compiler it pulling in the definitions from USAdittions.h twice via the other two classes but not ignoring the dups.
Am I wrong in understanding how #import works? Any ideas how to fix this?
I have seen a few similar posts but none of the solutions applied to me or helped me.
Are you certain you're importing the .h file and not the .m file?
If you #import the .m file the compiler pretty much copy-pastes the whole file, leading to redefinitions of methods and classes.
I've had that bite me this way in the past.
Besides Benoit's answer, do your .h files have #implementations in them? If so, then you're defining (not just declaring) the class in two translation units. The class definition ends up in both .o files and when linked, you get duplicate definitions.
Your header files should only have declarations, never definitions.

forward class declaration about #class

I know it is proper practice to put a forward class declaration (#class ClassA) in the .h and #import "ClassA.h" in the .m. And also I know doing that can make compiler compile it later on(until #import it in the .m).
Usually we use #class ClassA in A.h meanwhile add #import ClassA.h in A.m, though the compiler would not compile ClassA in A.h, still compiler have to compile it in the A.m.
So why not use #import in A.h directly?
You almost never use #Class A in A.h. The common practice is to use #Class B in A.h and #Class A in B.h. The reason for this is to avoid circular dependencies in the .h files. If A.h imported B.h and B.h imported A.h, the compiler would explode from the circular dependency.
Your last sentence seems to be asking why we never import A.h in A.h. I think it's pretty obvious why that isn't done.
Remember, the header file (.h) is meant to tell the world the minimum possible about your declarations. It's there to tell the compiler - "Hey, we have a class (#interface) with some methods and properties. And those methods use these other classes. We use #class for those other classes because at this point in time we only need to know that there will be such classes eventually. It's just enough to make the compiler happy so it can do its job. Ultimately, the linker makes the final decision about whether those classes really exist somewhere.
The source file (.m) needs to do the actual importing because the compiler needs to verify that there really are the methods and properties you are trying to use. But the header file doesn't call methods and it doesn't call properties. It simply states - "This stuff exists".
I use #class instead of #import in .h for two reasons:
Makes circular dependencies possible.
Reduces compile time.
I commonly find it useful to have mutual links, A->B and B->A, which is impossible without forward declarations.

Interdependent Class

Say class A depends on Class B and via versa.
So obviously in a.h I would put #import"b.h" and in "b.h" I would import "a.h"
After that
Should we
declare #class A
in b.h AND #class B in a.h
Should we do both or should we use #class only once?
Why?
I reasoned that if I do it only once, say including #class B in a.h, given that a.h also contains #import "b.h" then the class a.h already knows about b.h
However it seems that I got to do it both in xcode and I wonder why.
There's nothing wrong with using a forward declaration (i.e. #class Foo) in the header file for each class. You can do that if all you need is for each class to reference the other. A forward declaration just tells the compiler "This name refers to a class, and the actual declaration of the class will come later."
As you say, you could also use a forward declaration of B in A.h, and then just import A.h in B.h. I don't think there's any real benefit to doing that unless there are other things in A.h that you also need to reference in B.h.
However it seems that I got to do it
both in xcode and I wonder why.
If you mean that you're getting an error when you import A.h in B.h instead of using a forward declaration of A, please post the error. I don't think there should be a problem with that. (And in any case, the issue would be a compiler issue or an Objective-C issue, not an Xcode problem. Xcode is just the IDE.)
You should rethink your design, a circular dependency like this should not be needed.
What you probably want is to declare ClassA and ClassADelegate in ClassA.h. Next up declare ClassB in ClassB.h, and import ClassA.h from there, let ClassB conform to ClassADelegate protocol to resolve the circular dependency.
This way you get a clear ownership relation, and code that will be much easier to maintain and extend in the future.

#class vs. #import

It is to my understanding that one should use a forward-class declaration in the event ClassA needs to include a ClassB header, and ClassB needs to include a ClassA header to avoid any circular inclusions. I also understand that an #import is a simple ifndef so that an include only happens once.
My inquiry is this: When does one use #import and when does one use #class? Sometimes if I use a #class declaration, I see a common compiler warning such as the following:
warning: receiver 'FooController' is a forward class and corresponding #interface may not exist.
Would really love to understand this, versus just removing the #class forward-declaration and throwing an #import in to silence the warnings the compiler is giving me.
If you see this warning:
warning: receiver 'MyCoolClass' is a forward class and corresponding #interface may not exist
you need to #import the file, but you can do that in your implementation file (.m), and use the #class declaration in your header file.
#class does not (usually) remove the need to #import files, it just moves the requirement down closer to where the information is useful.
For Example
If you say #class MyCoolClass, the compiler knows that it may see something like:
MyCoolClass *myObject;
It doesn't have to worry about anything other than MyCoolClass is a valid class, and it should reserve room for a pointer to it (really, just a pointer). Thus, in your header, #class suffices 90% of the time.
However, if you ever need to create or access myObject's members, you'll need to let the compiler know what those methods are. At this point (presumably in your implementation file), you'll need to #import "MyCoolClass.h", to tell the compiler additional information beyond just "this is a class".
Three simple rules:
Only #import the super class, and adopted protocols, in header files (.h files).
#import all classes, and protocols, you send messages to in implementation (.m files).
Forward declarations for everything else.
If you do forward declaration in the implementation files, then you probably do something wrong.
Look at the Objective-C Programming Language documentation on ADC
Under the section on Defining a Class | Class Interface it describes why this is done:
The #class directive minimizes the amount of code seen by the compiler and linker, and is therefore the simplest way to give a forward declaration of a class name. Being simple, it avoids potential problems that may come with importing files that import still other files. For example, if one class declares a statically typed instance variable of another class, and their two interface files import each other, neither class may compile correctly.
Use a forward declaration in the header file if needed, and #import the header files for any classes you're using in the implementation. In other words, you always #import the files you're using in your implementation, and if you need to reference a class in your header file use a forward declaration as well.
The exception to this is that you should #import a class or formal protocol you're inheriting from in your header file (in which case you wouldn't need to import it in the implementation).
The common practice is using #class in header files (but you still need to #import the superclass), and #import in implementation files. This will avoid any circular inclusions, and it just works.
Another advantage: Quick compilation
If you include a header file, any change in it causes the current file also to compile but this is not the case if the class name is included as #class name. Of course you will need to include the header in source file
My inquiry is this. When does one use #import and when does one use #class?
Simple answer: You #import or #include when there is a physical dependency. Otherwise, you use forward declarations (#class MONClass, struct MONStruct, #protocol MONProtocol).
Here are some common examples of physical dependence:
Any C or C++ value (a pointer or reference is not a physical dependency). If you have a CGPoint as an ivar or property, the compiler will need to see the declaration of CGPoint.
Your superclass.
A method you use.
Sometimes if I use a #class declaration, I see a common compiler warning such as the following:
"warning: receiver 'FooController' is a forward class and corresponding #interface may not exist."
The compiler's actually very lenient in this regard. It will drop hints (such as the one above), but you can trash your stack easily if you ignore them and don't #import properly. Although it should (IMO), the compiler does not enforce this. In ARC, the compiler is more strict because it is responsible for reference counting. What happens is the compiler falls back on a default when it encounters an unknown method which you call. Every return value and parameter is assumed to be id. Thus, you ought to eradicate every warning from your codebases because this should be considered physical dependence. This is analogous to calling a C function which is not declared. With C, parameters are assumed to be int.
The reason you would favor forward declarations is that you can reduce your build times by factors because there is minimal dependence. With forward declarations, the compiler sees there is a name, and can correctly parse and compile the program without seeing the class declaration or all of its dependencies when there is no physical dependency. Clean builds take less time. Incremental builds take less time. Sure, you will end up spending a little more time making sure the all the headers you need are visible to every translation as a consequence, but this pays off in reduced build times quickly (assuming your project is not tiny).
If you use #import or #include instead, you're throwing a lot more work at the compiler than is necessary. You're also introducing complex header dependencies. You can liken this to a brute-force algorithm. When you #import, you're dragging in tons of unnecessary information, which requires a lot of memory, disk I/O, and CPU to parse and compile the sources.
ObjC is pretty close to ideal for a C based language with regards to dependency because NSObject types are never values -- NSObject types are always reference counted pointers. So you can get away with incredibly fast compile times if you structure your program's dependencies appropriately and forward where possible because there is very little physical dependence required. You can also declare properties in the class extensions to further minimize dependence. That's a huge bonus for large systems -- you would know the difference it makes if you have ever developed a large C++ codebase.
Therefore, my recommendation is to use forwards where possible, and then to #import where there is physical dependence. If you see the warning or another which implies physical dependence -- fix them all. The fix is to #import in your implementation file.
As you build libraries, you will likely classify some interfaces as a group, in which case you would #import that library where physical dependence is introduced (e.g. #import <AppKit/AppKit.h>). This can introduce dependence, but the library maintainers can often handle the physical dependencies for you as needed -- if they introduce a feature, they can minimize the impact it has on your builds.
I see a lot of "Do it this way" but I don't see any answers to "Why?"
So: Why should you #class in your header and #import only in your implementation? You're doubling your work by having to #class and #import all the time. Unless you make use of inheritance. In which case you'll be #importing multiple times for a single #class. Then you have to remember to remove from multiple different files if you suddenly decide you don't need access to a declaration anymore.
Importing the same file multiple times isn't an issue because of the nature of #import.
Compiling performance isn't really an issue either. If it were, we wouldn't be #importing Cocoa/Cocoa.h or the like in pretty much every header file we have.
if we do this
#interface Class_B : Class_A
mean we are inheriting the Class_A into Class_B, in Class_B we can access all the variables of class_A.
if we are doing this
#import ....
#class Class_A
#interface Class_B
here we saying that we are using the Class_A in our program, but if we want to use the Class_A variables in Class_B we have to #import Class_A in .m file(make a object and use it's function and variables).
for extra info about file dependencies & #import & #class check this out:
http://qualitycoding.org/file-dependencies/
itis good article
summary of the article
imports in header files:
#import the superclass you’re inheriting, and the protocols you’re implementing.
Forward-declare everything else (unless it comes from a framework
with a master header).
Try to eliminate all other #imports.
Declare protocols in their own headers to reduce dependencies.
Too many forward declarations? You have a Large Class.
imports in implementation files:
Eliminate cruft #imports that aren’t used.
If a method delegates to another object and returns what it gets
back, try to forward-declare that object instead of #importing it.
If including a module forces you to include level after level of
successive dependencies, you may have a set of classes that wants to
become a library. Build it as a separate library with a master
header, so everything can be brought in as a single prebuilt chunk.
Too many #imports? You have a Large Class.
When I develop, I have only three things in mind that never cause me any problems.
Import super classes
Import parent classes (when you have children and parents)
Import classes outside your project (like in frameworks and libraries)
For all other classes (subclasses and child classes in my project self), I declare them via forward-class.
If you try to declare a variable, or a property in your header file, which you didn't import yet, your gonna get an error saying that the compiler doesn't know this class.
Your first thought is probably #import it.
This may cause problems in some cases.
For example if you implement a bunch of C-methods in the header file, or structs, or something similar, because they shouldn't be imported multiple times.
Therefore you can tell the compiler with #class:
I know you don't know that class, but it exists. It's going to be imported or implemented elsewhere
It basically tells the compiler to shut up and compile, even though it's not sure if this class is ever going to be implemented.
You will usually use #import in the .m and #class in the .h files.
Forward declaration just to the prevent compiler from showing error.
the compiler will know that there is class with the name you've used in your header file to declare.
Compiler will complain only if you are going to use that class in such a way that the compiler needs to know its implementation.
Ex:
This could be like if you are going to derive your class from it or
If you are going to have an object of that class as a member variable (though rare).
It will not complain if you are just going to use it as a pointer. Of course, you will have to #import it in the implementation file (if you are instantiating an object of that class) since it needs to know the class contents to instantiate an object.
NOTE: #import is not same as #include. This means there is nothing called circular import. import is kind of a request for the compiler to look into a particular file for some information. If that information is already available, compiler ignores it.
Just try this, import A.h in B.h and B.h in A.h. There will be no problems or complaints and it will work fine too.
When to use #class
You use #class only if you don't even want to import a header in your header. This could be a case where you don't even care to know what that class will be. Cases where you may not even have a header for that class yet.
An example of this could be that you are writing two libraries. One class, lets call it A, exists in one library. This library includes a header from the second library. That header might have a pointer of A but again might not need to use it. If library 1 is not yet available, library B will not be blocked if you use #class. But if you are looking to import A.h, then library 2's progress is blocked.
Think of #class as telling the compiler "trust me, this exists".
Think of #import as copy-paste.
You want to minimize the number of imports you have for a number of reasons. Without any research, the first thing that comes to mind is it reduces compile time.
Notice that when you inherit from a class, you can't simply use a forward declaration. You need to import the file, so that the class you're declaring knows how it's defined.
This is an example scenario, where we need #class.
Consider if you wish to create a protocol within header file, which has a parameter with data type of the same class, then you can use #class. Please do remember that you can also declare protocols separately, this is just an example.
// DroneSearchField.h
#import <UIKit/UIKit.h>
#class DroneSearchField;
#protocol DroneSearchFieldDelegate<UITextFieldDelegate>
#optional
- (void)DroneTextFieldButtonClicked:(DroneSearchField *)textField;
#end
#interface DroneSearchField : UITextField
#end