Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable declaration difference in Objective-C

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
like image 585
Midhun MP Avatar asked Nov 22 '12 14:11

Midhun MP


People also ask

How variable declaration in C++ differs that in C?

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.

What is the difference between variable declaration?

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.

What is the difference between type declaration and variable declaration?

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.

What is variable declaration in C?

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.


1 Answers

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);
}
like image 165
AliSoftware Avatar answered Sep 19 '22 14:09

AliSoftware