Why is #import deprecated? - objective-c

I understand how #import works vs #include, the whole "Only include it if it isn't already included" thing. I also understand that Apple is pretty fond of #import for their Objective-C code, so over in Xcode it's not going anywhere and everything's fine.
What I don't get is in other environments like Android Studio, it says that #import is deprecated and gives warnings if you use it. Why is that?
It's my understanding that #import is functionally different and, in some cases, arguably better than #include, depending on what you need. If that's the case, why deprecate a potentially useful tool, especially if there isn't any sign of it being replaced with something better?
Is there some horrendous flaw in it that makes it wholly undesirable to use, or is it fine?

Because Objective-C is a superset of the C programming language, the #import statement is a minor refinement upon C’s #include statement. The #include statement is very simple; it copies everything it finds in the included file into your code during compilation. This can sometimes cause significant problems. This can creates a loop, and can confuse the compiler. To deal with this, C programmers have to write guards against this type of event from occurring.
When using #import, you don’t need to worry about this issue or write header guards to avoid it. However, #import is still just a glorified copy-and-paste action, causing slow compilation time among a host of other smaller but still very dangerous issues (such as an included file overriding something you have declared elsewhere in your own code.)
From iOS 7, Apple introduced a new way to import file:
#import UIKit;
It's a new feature called Modules or "semantic import". Modules are an attempt to get around above issue. They are no longer a copy-and-paste into source code, but a serialized representation of the included files that can be imported into your source code only when and where they’re needed. By using modules, code will generally compile faster, and be safer than using either #include or #import.
To get more information about this, you can watch WWDC 2013

Related

Usage of #import -- General guidelines for using #import in very large projects (ObjC)

Where do #import my headers and implementations?
Are there rules regarding what I should do?
Is there a way to import everything in a single header file?
Given "General guidelines for using #import in very large projects.".
Well, Objective-C is much like C and C++ in this regard. Stuffing all your #includes/#imports into your headers will introduce a lot of unnecessary dependency, which adds a lot of time to your build. So further information may also be sought in topics on C and C++ dependencies.
Where do #import my headers and implementations?
Typically, you should write #import only where physical dependency exists. Since every objc object is reference counted and your properties/ivars do not typically need to exist in the header, #imports are far lower than C++.
Robin van Dijke outlined the common cases of physical dependence in his answer (+1).
Are there rules regarding what I should do?
Is there a way to import everything in a single header file?
Well, it depends on the size of your project. Some people add all frameworks they use to the PCH (Pre-Compiled Header). Some people put the most frequent ones in the PCH, and some people don't use PCH files at all. The longer the build times and more complex the project, the less the PCH should include.
If you are working on "Very Large" projects, you should probably not add more than Foundation to your PCH.
Another common mistake is that some people will use the PCH so they need to type less (pretty much). The problem with that is their project's common includes/headers change, and when that happens, the target must be entirely rebuilt.
Also, if you can avoid #importing frameworks/libraries in your headers, you can save a lot of build time.
Adding #imports to headers increases causes dependencies to spread even further. It's easy for tons of unrelated code/frameworks which only need to be visible to a few source files to be actually visible to a high percentage of your source files.
Finally, you should really try to keep headers which change often out of other headers.
The big takeaway is that you should:
separate your programs based on features
favor forward declarations over #import. the compiler must know names, but the import is often needed only when you create/message the object.
try to keep your dependency-heavy implementations in the *.m file.
Every once in a while, it can help to review the preprocessed output of some of your source files -- to see what is actually #imported -- the results can be quite surprising.
Notes:
The PCH must be generated for every language in your project.
Compile sources based on their needs; e.g. If you have C programs, don't compile them as ObjC.
As your project's complexity increases, the gains to be made by dividing by targets (e.g. static libraries, modules, dividing your tests logically...) will increase. Structuring dependent targets correctly with low dependency is a large topic in itself. It can really help you build and test at higher frequencies when structured correctly (also important if you use continuous integration or have several developers). Like header dependencies, if you don't consider this from the start, old problems can take a lot of man-hours to correct (after it's already grown to be unbearably slow).
The following conventions can be used:
Use #import in your header file when
- You subclass the imported class
- You use a protocol from the imported header file
- You use other C datastructures (enum, struct) from the imported header file
Example:
#import "SuperClass.h"
#import "Protocol.h"
#class SomeOtherClass
#interface Subclass : SuperClass <Protocol>
SomeOtherClass _instanceVariableToOtherClass
#end
Otherwise use #class in the header file
For all other cases, use #import in the .m file.
Note: #import "class.h" is in fact the following:
#pragma once
#include "class.h"
So it takes care that every class is only imported once to prevent include cycles/loops.
First read this official site That may be helpful for you.
It is similar like , #include Statement In the C language,
Basically #import statement has two Defination,
1) #import "headerFile.h" // This statement is use for Import any header file in current file (UIController)
2) #import<FramWorkName> // This statement basically use for add any framework in current file (UIController)
For use any file any where in your Project then add your file (#import "fileName.h") in .pch file. It is Prefix headers are compiled and stored in a cache, and then automatically included in every file during compilation. This can speed up compilation, and lets you include a file without adding an import statement to every file using it. They are not required, and actually slow compilation whenever you change them. This file is available in your project with .pch file extension.
Such Like:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "MyFile_Name.h"
Your can also use PROTOCOL for to define methods that are to be implemented by other classes.
For More information about, How to create POTOCOL, here is Best example with detail.
Just for kicks - I'm going to add a few "basic tenets" - that although are not as detailed as what has been said already - can sometimes help understand the overall "process".
Implementation.m files are never (as far as I know) #import'ed - that is what the compiler "is doing" when it "compiles".
Any header you want ALL compiled (.m) files to "know about" can go in the .pch file. I usually also stick directives shared across all classes, i.e. #import <Cocoa/Cocoa.h>, etc in there - so I don't have to look at them in every file.
If you are going to reference a previously undeclared class in a header file, i.e. AppDelegate.h
#property (nonatomic, strong) HTTPServer *http;
you can #import "HTTPServer.h" at the top of that file (or even in the.pch`)... but it is usually better to reference the "forward class" as follows...
#class HTTPServer;
#interface AppDelegate : NSObject ➜ ...
and then #import "HTTPServer.h" in AppDelegate's .m file. The main reason that you need access to the header file... is to call methods and work with properties, etc of an instance of that external class within your own class's "scope". This is why you can "get away with" simply "mentioning" the #class in your header - you're not actually doing anything with it yet.
The only other thing to consider - and this probably isn't the case if you're building a standalone application - but when building a framework, or a bundle, etc… in which YOUR classes will be referenced in an "API-kind-of-way"… You would want to add a "Copy Files" phase to your build process which would allow "others" to "know about" your classes, via your "Public Header" files. In such a case... you can simply expose a header file which imports the forward declarations needed for your class, for other people to #import. This is how you are able to access all the classes in an "Umbrella Framework", such as <Foundation/Foundation.h> with a single #import... It has exposed the headers that it "makes available" in that first `.h' file.. á la...
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
If you ever used compiler before Xcode, the way to think about it is that any header you need to import are the same as an "Include" -I directive on the commandline. Given a header file src/headers/header.h and a source code file source.c which has an #include "header.h" statement.. the compile command would be
gcc -Iheaders/ source.c -o executable
You can learn about what is actually happening when you compile something in Xcode by navigating to the "log navigator" and Xcode and checking out all the steps.

#include or #import <objc/runtime.h>?

For an iPhone app, should I #include or #import , and why?
I've seen it done both ways, e.g., #import & #include.
If the header file has traditional include guards, it really doesn't matter which you use, it's more of a stylistic choice. There might be a tiny performance boost if you use #import instead of #include, but I doubt it will be noticeable, since most compilers these days are smart enough to recognize include guards and optimize accordingly.
If, on the other hand, the header file does not have include guards, then you should always use #import, since #import will ensure that the header will only get included once -- if you accidentally #include such a header twice, you will almost certainly get a deluge of compiler errors about redefinitions etc.
Since most Objective-C headers (especially those coming from the Objective-C runtime or the Cocoa headers) do not have include guards, you should use #import when including those. When including standard C library headers or headers from a third-party library, it doesn't matter which you choose -- pick one style and be consistent.
use #import. the advantage is that it does not "re-include" files if they've already been included.
Always use #import - it will make sure that the same header file is never #include'd twice.

decompiling Objective-C preprocessor statements

Please forgive me if this is an obvious question or if there are any errors. I am very new to Objective-C and have kind of been thrown in the deep end.
I am looking into Objective-C obfuscation. On simple method of this that I found here is to user the preprocessor to change method names to gibberish. My question is whether a decompiler can recognize preprocessor statements, such that it would be able to decompile the source back to the original method names. The example from the above referenced question is below:
#ifndef DEBUG
#define MyClass aqwe
#define myMethod oikl
#endif
#interface MyClass : NSObject {
}
- (void)myMethod;
Is it possible for, when not compiled for debugging, this code could be decompiled back to anything other than
#interface aqwe : NSObject {
}
- (void)oikl;
You could absolutely not un-obfuscate that. The preprocessor runs before the compiler gets its greasy paws on the code, so it's just as if you had manually gone through and replaced all occurrences of MyClass with aqwe, etc.
Although, you should ask yourself why you want to do this. It's just obfuscation remember, rather than actually securing anything about your code. People could still look and see the code that each method comprises. You're just changing the name of symbols.
You'll save yourself a lot of time, pain and trouble if you just choose to use one the many existing obfuscators availible instead of trying to reinvent the wheel.
Take a look at this thread, you'll find lot of useful information for a starter:
https://stackoverflow.com/questions/337134/what-is-the-best-net-obfuscator-on-the-market

Any downside to never creating ObjC files but always creating ObjC++ files instead?

By default Xcode creates both an .h and and an .m file when you ask for a new ObjC class.
Everything works fine until you need to refer to any C++ file elsewhere in your project and start #import ing it into either your .h or .m file
At that point, the ObjC compiler gest utterly confused and throws mountains of parsing errors, and you the user (that is to say: me) get even more confused until such time it hits me: of course I should make that file an ObjC++ file instead.
The options are:
tell Xcode that this particular file, even though it is a .m file
really is an ObjC++ file, or
rename that file to .mm.
The first option is not very palatable to me, because that file really is ObjC++ regardless of the what the project thinks it is.
The second option is not good either as it screws up the Git repo which then 'forgets' that there used to be another .m file which really is the history of this 'new' .mm file.
So I have decided from now on to always rename any .m file that Xcode creates for me to .mm first thing after creating it so that I won't loose the history.
It has worked well for me so far, but I have this slight worry in my head, that there might be some corner case where I would really want to have an ObjC file and not an ObjC++ file.
What would those corner cases be? Anyone is aware of any ObjC++ file which happens to NOT contain any C++ reference but would choke the ObjC compiler in some way, just by virtue of being an .mm file?
And if there are no downside, why not just deprecate the use of .m forever and stick to .mm instead?
Parsing C++ is much slower than parsing ObjC, so ObjC++ files have significantly longer compile times. I'm not certain if this overhead will apply to ObjC++ files that contain no C++, but it would make a certain amount of sense that it's harder to parse just because the compiler needs to look for C++ constructs.
Also, the C++ type system has a few slightly different rules from C, that are applied to ObjC/C code in a C++ file as well. I don't recall the details, but it's not going to be harmful; just might require a few extra casts.
There is no downside, although there are two methods created on behalf of you (.cxx_construct and .cxx_destruct), but they are only used for crafting and destroying C++ objects when you create/dealloc an instance. If your class has no C++ members, these functions do nothing and add only an really extremely low overhead. Otherwise, you still have C functions generated for your Objective-C methods, not C++ functions.
Create an Objective-C++ file template so you get a .mm file instead of a .m file when you create a new file. Make a copy of Apple's Objective-C class templates and rename the .m files to .mm. More detailed information on creating Xcode 4 file templates is available in the following article:
Creating Custom Xcode 4 File Templates
Language incompatibilities aside, one reason to avoid an entirely .mm project is that you might end up being tempted to start sections of your methods in c++, which will result in a project written in a (relatively obscure) hybrid of two languages, and will only be understood by people who know both. (I have done this before)
A nice way to avoid cluttering your obj-c headers with c++ is to declare instance variables in your implementation file (which is allowed as of xcode 4.2/clang 3.0, possibly earlier). Eg:
#implementation MyClass {
std::vector<int> myVector;
}
This helps to keep the points of contact between objective-c and c++ minimised.
I use .mm file exclusively for my iOS code and have never had any issues. Yes, my compiles are a little slower in that a clean compile takes 15 seconds vs 10 seconds. At least on a iMac, it's not significant.

#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