I'm was reading a tutorial about coreImage in iOS 6. In that tutorial I found something like:
@implementation ViewController {
CIContext *context;
CIFilter *filter;
CIImage *beginImage;
UIImageOrientation orientation;
}
//Some methods
@end
The variables are declared in the .m file in a parenthesis after the @implementation statement. I'm seeing these kind of variable declaration first time.
Is there any difference between the above variable declaration and the following code
@implementation ViewController
CIContext *context;
CIFilter *filter;
CIImage *beginImage;
UIImageOrientation orientation;
//Some methods
@end
C requires all the variables to be declared at the beginning of a scope but in c++ we can declare variables anywhere in the scope. This makes the programmer easier to understand because the variables are declared in the context of their use.
The main difference between Declaration and Definition in C is that declaration of a variable indicates the compiler about the name and the type of the variable, while the definition of a variable indicates the compiler where and how much storage to create for a variable.
The typedef keyword acts somewhat like a storage class specifier in a variable declaration, the only difference being that the resulting typedef_name is marked as a type name and not as a variable name.
Variables are containers for storing data values. In C, there are different types of variables (defined with different keywords), for example: int - stores integers (whole numbers), without decimals, such as 123 or -123. float - stores floating point numbers, with decimals, such as 19.99 or -19.99.
There is a HUGE difference.
Variables inside brackets directly after the @interface
or @implementation
are instance variables. These are variables associated with each instance of your class, and thus accessible anywhere in your instance methods.
If you don't put the brackets, you declare global variables. Any variable declared outside of any bracket block will be a global variable, whether these variables are before or after the @implementation
directive. And global variables are evil and need to be avoided at all costs (you can declare global constants, but avoid global variables), especially because they are not thread-safe (and may thus generate bugs that are a mess to debug).
In fact, historically (in first versions of Objective-C and the compilers), you were only able to declare instance variables in brackets after your @interface
in your .h
file.
// .h
@interface YourClass : ParentClass
{
// Declare instance variables here
int ivar1;
}
// declare instance and class methods here, as well as properties (which are nothing more than getter/setter instance methods)
-(void)printIVar;
@end
// .m
int someGlobalVariable; // Global variable (bad idea!!)
@implementation YourClass
int someOtherGlobalVariable; // Still a bad idea
-(void)printIVar
{
NSLog(@"ivar = %d", ivar1); // you can access ivar1 because it is an instance variable
// Each instance of YourClass (created using [[YourClass alloc] init] will have its own value for ivar1
}
Only modern compilers let you declare instance variables (still in brackets) also inside either your class extension (@interface YourClass ()
in your .m implementation file) or in your @implementation
, in addition to the possibility to declare them after the @interface
in your .h
. The benefits being to hide those instance variables from external users of your classes, by declaring them in the .m file and not in the .h file anymore, because users of your class don't need to be aware of the internal coding details of your class, but only needs to know the public API.
One final advice: instead of using instance variables, Apple more and more recommends to use @property
directly, and let the compiler (explicitely using the @synthesize
directive, or implicity with modern LLVM compilers) generate the internal backing variable. So that at the end you generally won't need to declare instance variables at all, and thus omit the empty { }
after the @interface
directive:
// .h
@interface YourClass : ParentClass
// Declare methods and properties here
@property(nonatomic, assign) int prop1;
-(void)printProp;
@end
// .m
@implementation YourClass
// @synthesize prop1; // That's even not needed with modern LLVM compiler
-(void)printProp
{
NSLog(@"ivar = %d", self.prop1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With