Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C instance variables?

Tags:

objective-c

I'm sure my confusion here is just a result of being stuck in a "Java mindset" and not understanding how Obj-C differs in this case.

In Java, I can declare a variable in a class, like this, and each instance of that class will have it's own:

MyClass {

  String myVar;

  MyClass() {
    // constructor
  }
}

In Obj-C I tried to do the same thing by declaring a variable only in the .m file like this:

#import "MyClass.h"

@implementation MyClass

NSString *testVar;

@end

My expectation here was that this variable has a scope limited to this class. So I created a second class (identical):

#import "MySecondClass.h"

@implementation MySecondClass

NSString *testVar;

@end

What I'm seeing (and has me baffled) is that changing the variable in one class, affects the value seen in the other class. In fact, if I set a breakpoint, and then "Jump to Definition" of the variable, it takes me to th

I've created an extremely small Xcode project that demonstrates the problem here.

like image 733
Dwayne King Avatar asked Nov 07 '12 04:11

Dwayne King


People also ask

What is instance variable Objective-C?

An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc ), and freed when the object is deallocated.

What is the difference between property and instance variable?

A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.

What is @property in Objective-C?

The goal of the @property directive is to configure how an object can be exposed. If you intend to use a variable inside the class and do not need to expose it to outside classes, then you do not need to define a property for it. Properties are basically the accessor methods.


1 Answers

Change this:

@implementation MyClass

NSString *testVar;

@end

to:

@implementation MyClass {
    NSString *testVar;
}

// methods go here

@end

and you'll get what you expected.

As you had it, you are actually creating a global variable. The two global variables were combined into one by the linker which is why both changed when you set one. The variable in curly braces will be a proper (and private) instance variable.

Edit: After being downvoted for no apparent reason, I thought I'd point out the "old" way of doing things, and the new way.

The old way:

SomeClass.h

@interface SomeClass : UIViewController <UITextFieldDelegate> {
    UITextField *_textField;
    BOOL _someBool;
}

@property (nonatomic, assign) BOOL someBool;

// a few method declarations

@end

SomeClass.m

@implementation SomeClass

@synthesize someBool = _someBool;

// the method implementations

@end

Now the new and improved way with the modern Objective-C compiler:

SomeClass.h

@interface SomeClass : UIViewController

@property (nonatomic, assign) BOOL someBool;

// a few method declarations

@end

SomeClass.m

@interface SomeClass () <UITextFieldDelegate>
@end

@implementation SomeClass {
    UITextField *_textField;
}

// the method implementations

@end

The new way has several advantages. The primary advantage is that none of the implementation specific details about the class appear in the .h file. A client has no need to know what delegates the implementation needs. The client has no need to know what ivars I use. Now, if the implementation needs a new ivar or it needs to use a new protocol, the .h file doesn't change. This mean less code gets recompiled. It cleaner and much more efficient. It also makes for easier editing. When I'm editing the .m file and realize I need a new ivar, make the change in the same .m file I'm already editing. No need to swap back and forth.

Also note the implementation no longer needs an ivar or @synthesize for the property.

like image 73
rmaddy Avatar answered Oct 19 '22 09:10

rmaddy