I have this enumeration:
enum battleType {localEnemy,multiplayerEnemy};
Which is declared in the .h file of my game battle scene. However, I would like to also use those two keywords in my party screen (which is another .h file). Do I have to declare this same enumaration twice (in both .h files), or is there a way to just declare it once and use it everywhere in my project?
As a side note, those keywords are exactly the same as integers, right? So I can't really store them as objects in my array, and instead I have to create a NSNumber instance for this, right?
Declare it in the header file it belongs into. In your case that would probably be BattleScene.h or something like that.
In the other file where you also have to use it you #import BattleScene.h.
If you use typedef, you don't have to write enum all the time. Also, it a good practice to use a uniform prefix in your enums. This makes your code more readable and autocomplete can help you when using the enum.
typedef enum {BattleTypeLocalEnemy, BattleTypeMultiplayerEnemy} BattleType;
There is a way. Create a new .h file (New File -> C and C++ -> Header) and put in your enum. Then just #import it into the battle scene header and the party scene header.
Your other question: Yes, they are really ints, shorts, or some other C integer type.
My obj-c class uses a C library (the Chipmunk physics engine), which has an Obj-C wrapper interface.
I want to add a property with a chipmunk type (cpLayers) to my object, like so:
#interface
#property cpLayers layers;
...
The easiest way is to #import "ObjectiveChipmunk.h", but that seems ridiculous to import all of the headers just to get one measly type.
If I #import the C "chipmunk_types.h" file where cpLayers is defined "typedef unsigned int cpLayers;", I get compiler errors related to ARC. They are bridge/casting errors in a macro that is defined in chipmunk_types.h and used in my .m file.
If I add just the definition, or #include chipmunk_types.h, I get redefinition errors.
Is there any better way to do this? And WHY the ARC errors?
Take a look at the ObjectiveChipmunk.h, that is where it overrides the basic Chipmunk types using preprocessor defines. You can add those defines as compiler flags if you want to work around the problem, but I wouldn't really worry about it. You are already doing Objective-C programming after all, have you ever looked at the gargantuan amount of includes that get pulled in when you import something as innocuous as Foundation.h? Importing the full ObjectiveChipmunk.h header is like 1% in comparison.
in one header file I have something like:
typedef void (^MyBlock)(void);
I need to use that same exact reference in another header file.
Sure, I can #import one header file into another, or include the typedef in the global pre-compiled header, but instead is there a way to forward reference the block typedef?
Not as far as I know, I'd just put it in a shared header and include it where it is needed.
When I compile with the following code there are no errors:
#class RootViewController;
//#import "RootViewController.h"
When I compile with the following code I get an error:
//#class RootViewController;
#import "RootViewController.h"
"error: expected specifier-qualifier-list before 'RootViewController'"
I don't understand what the difference is between the two because I used #import in a similar class and it compiled without errors!
#class is used when you need to know the name of a class in a particular file, but you don't need to know any details about the class (its methods, for example). #import is used when you actually need to use the class (i.e., send it a message).
For example, if you're declaring instance variables in a header file, you can use #class to declare an instance variable of a certain type:
#class MyOtherClass;
#interface MyClass : NSObject
{
MyOtherClass *myIvar;
}
#end
Since you're not using myIvar yet, you don't need to know anything about it except that the type MyOtherClass exists.
However:
#import "MyOtherClass.h"
- (void)doSomething
{
[myIvar doSomethingElse];
}
In this case, you're sending the doSomethingElse message to myIvar; the compiler needs to know that instances of MyOtherClass define this method, so you have to import the header file or the compiler will complain.
Why worry about this?
It mostly has to do with dependencies. When you #import file A into file B, file B becomes dependent upon file A -- that is, if file A changes, you'll have to recompile file B. If you use #class in file B, file B is not dependent on file A, and thus doesn't need to be recompiled when file A changes -- so if you're just declaring a type and not actually dependent upon the implementation of file A, you can save yourself compilation time by not #importing file A.
I decided to refer to the documentation because I was still confused:
#import
This directive is identical to #include, except that it makes sure that the same file is never included more than once. It’s therefore preferred and is used in place of #include in code examples throughout Objective-C–based documentation.
This convention means that every interface file includes, indirectly, the interface files for all inherited classes. When a source module imports a class interface, it gets interfaces for the entire inheritance hierarchy that the class is built upon.
#class
Declarations like this simply use the class name as a type and don’t depend on any details of the class interface (its methods and instance variables), the #class directive gives the compiler sufficient forewarning of what to expect. However, where the interface to a class is actually used (instances created, messages sent), the class interface must be imported.
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF123
Basic rule: use #class in you header file and #import in your implementation file.
(However, you need to #import your class' superclass. And in some other circumstances you also need to use `#import" in the header.)
#import is not equivalent to #include. If a file is included many times, it will be loaded each time, but with many #imports of the same file, it will still only be loaded once.
Therefore, the main reason to use #class is not to avoid circular dependencies, but to make compilation faster.
Here's an example of when you must use #class
//MYControl.h
#class MYControl; // Must use class
#protocol MYControlDelegate
-(void)control:(MYControl *)control didChangeToState:(UIControlState)state;
#end
#interface MYControl : UIControl
{
id<MYControlDelegate> delegate_;
}
#property (nonatomic, assign) id<MYControlDelegate> delegate;
#end
//MYControl.m
#implementation MYControl
#synthesize delegate = delegate_;
. . .
In this case, there is nothing to import, because the delegate protocol is declared above the main class in the header file. But you still need to be able to refer to the main class which has not yet been declared. So what #class does is to just let the compiler know that there is some class that is called MYControl and will be defined at some point. (Not at runtime however. The class will be defined in the course of the compilation.)
EDIT: From the Objective-C manual:
Since declarations like this simply
use the class name as a type and don’t
depend on any details of the class
interface (its methods and instance
variables), the #class directive gives
the compiler sufficient forewarning of
what to expect. However, where the
interface to a class is actually used
(instances created, messages sent),
the class interface must be imported.
Typically, an interface file uses
#class to declare classes, and the
corresponding implementation file
imports their interfaces (since it
will need to create instances of those
classes or send them messages).
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.
Note that circularity is mentioned in the last sentence as one in a general class of issues dealt with by using #class.
#class is used to avoid circular dependency... This prevents circular references where in one header A imports a second header B which(B) imports the first(A) which imports the second (B)and so on in an endless cycle....#class is generally used to ask compiler to look for its definition at runtime... especially when it resides in some static library..
Other than that #import works
See this question
#class:- It defines that you can create instance variable of the imported class and use it in your class.
import:- It defines that you can access the variables declared in the required imported class.
you can use given link for more info.
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF123
#class means that the definition of the class RootViewController is not yet declared, but will be defined at run time. I believe it is like declaring an extern class in c++.
#import is equivalent to #include.
by the error message i could guess you just made a mistake somewhere inside RootViewController.h, such as a forgotten ; or something like that
you must have imported the this class in the class to which you want to import here. That is why you are getting error , but it can be rectify by #class example .
#class is a forward declaration, a good practice is to put them in the .h instead of #import for avoiding circular #import problem.
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. ;-)