Does Objective-C load the whole #imported file? - objective-c

I'm trying to understand what really happens at compile time and runtime with imported files.
Does #import "file.h" directive essentially copy and paste the entire file.m into the current file? Or does it just specify that file's location and create the necessary attributes as they are instantiated?

The imports are handled by the preprocessor in C, C++, and Objective C, which creates one large file for the compiler. Every *.m, *.c, *.cpp file will each get all of the imports.
You can compile code on the command line with the -E flag to see the result after all the #imports are added.
Additionally, this question goes into some detail about #include vs #import, so it might give you more insight:
What is the difference between #import and #include in Objective-C?
As you can image, having lots of extra imports slows compilation. Jetbrain's AppCode has a feature that will optimize imports:
http://www.jetbrains.com/objc/features/

Does #import file.h statement essentially copy and paste the entire file.m into the current file?
It is not a statement, it is a preprocessor directive.
You're missing quotes or angle brackets around the file name.
#import "file.h" does indeed copy the whole file.h file in place of this directive into the current file. It doesn't, however, do anything with file.m.

Related

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.

How to avoid "Redefinition" and "Duplicate Protocol" definition errors in Bridging Header

I want to use a objc library and a objc class in a swift class. So I place the following in the Bridging-Header.h:
#import <FooLibrary/FooLibrary.h>
#import "FooClass.h"
The problem is that the FooClass.h has
#import "FooLibrary.h".
So when I compile I get hundreds of errors like:"Redefinition of enumerator" and "Property has previous definition" and "Duplicate protocol definition" and "Typedef redefinition"
How do I avoid this? It seems like this is just a stupid mental block I am having but I can't get past it so here I am asking.
PartiallyFinite suggested I watch for #include
I did a project wide search and I and not using it at all. There are a few in the library. I chose one of the errors. The file the decoration is in is never included in any file with #include
Sounds like something is causing the preprocessor to believe that the FooLibrary.h header imported indirectly by the second #import is somehow not the same file as the one you include just above it. My best guess as to what is that your first, framework-style import is referencing header files that are copied to a build location during build, while your second, direct file import is referencing the header file as it is in your project directory, meaning that the preprocessor sees them as two completely separate files, resulting in it being imported twice.
Proposed ways to fix:
If you can include FooClass.h using the framework-style import syntax (like #import <FooLibrary/FooClass.h>), that will probably fix the problem.
If you're absolutely sure that FooClass.h will always include FooLibrary.h, you can probably just omit the first import entirely, as everything will get imported indirectly via the second one.
Otherwise, you can try some nice, old-fashioned include guards (assuming you have write access to the library headers):
// FooLibrary.h
#pragma once // Maybe even throw in one of these for good measure;
// since we're dealing with an obscure-sounding bug,
// may as well try to fix it in all of the possible ways
#ifndef FOOLIBRARY_IMPORTED
#define FOOLIBRARY_IMPORTED
... // actual file contents
#endif
This will define a preprocessor macro the first time the file is imported, so the second time the preprocessor tries to import the file, the already defined macro will prevent the contents from being imported a second time. I fail to understand why the #import isn't doing this in your case, as that's literally its only purpose and advantage over #include, but if this fixes it, ¯\_(ツ)_/¯
This can also be caused by cocoapods - try upgrading or downgrading to a different version and re-running pod install
For me it was happening when I upgraded Xcode. All I did was to Clean Build folder and run again and it worked!

#include <new> not found, but only when the file is referenced from a specific header?

I reference the FBXSDK from a number of files, but one in particular causes this error to crop up. The particular header just imports the fbxsdk like so:
#import "fbxsdk.h"
I also reference it from the .mm file, and compiling with just the .mm referencing it works fine. It's only when I import in the header that the fbxsdk brings up errors like this:
include/fbxfilesdk/fbxfilesdk_memory.h:67:15: error: new: No such file or directory
and a bunch of expected '*' before '*' errors. I'm guessing it has to do with the compile order, or it's compiling the fbxsdk with a different rule set after reading the initial header? I'm still learning how to work with different compilers and libraries, so any suggestions or clues as to where to look for a solution would be helpful.
Working with Xcode, in a mix of Obj-C++ and C.
Chances are you are trying to import fbxsdk.h from a .m file, not a .mm file. If you're importing fbxsdk.h in one of your own .h files, you need to be sure that your own .h file is only imported by .mm files, not .m files.

Compile cxx files in xcode

I am new at IPHone development , I included a library with .cxx as implementation class and a .h header but still i get error at compiling , Please any help?
I get errors at lines like below
class StackEvent;
The Objective-C class that is including any C or C++ code must be renamed with a ".mm" suffix rather than ".m" in the implementation class.
Any Objective-C file (.m) that includes any header containing C++ code, either directly or by chained #includes, will likely fail with compile errors.
You need to rename all your .m files to .mm if they can "see" your C++ header.
If that causes too much renaming, then you'll have to limit your #includes, for example by take the C++ #include out of your header file and putting it only in the .mm files that need it.

Link to a constants file in Cocoa / Xcode

In reference to this related question on stackoverflow:
If you create a constants file, how do you "link" to it in your target, so you don't have to
#import "Constants.h"
in every file you use constants?
You really should be using #import "Constants.h" every place you want to use the constants within it; Objective-C is a C-based language.
Furthermore, you aren't "linking" to it either when you put an #import directive in your code or if you put one in your prefix file. In both cases, the contents of the file are included in the text stream fed to the compiler by the preprocessor.
Finally, you shouldn't generally add random things to your prefix file. (Panagiotis Korros referred to this as "your pre-compiled header file," but that's slightly incorrect; your prefix file is used to generate the pre-compiled header file.) If you keep your build settings consistent across projects, and use the same name for your prefix files across projects, Xcode will actually cache and re-use the precompiled versions for you very aggressively. This is defeated by putting project-specific contents in them.
You can put the import line in your pre-compiled header file.
That is the .pch file named after you application name.
When I use the constant in more file inside my application, normally I use the .pch file (find it under "Supporting Files" folder).
Into my .pch file I insert the constant, for example:
static const int NAME_CONSTANT = 200;
and use NAME_CONSTANT into all file inside my project without import never file because the .pch is pre-compiled header file.