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
There is a HUGE difference.
Variables inside brackets directly after the
@interfaceor@implementationare 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
@implementationdirective. 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
@interfacein your.hfile.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@interfacein 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
@propertydirectly, and let the compiler (explicitely using the@synthesizedirective, 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@interfacedirective: