Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax for accessing instance variables? (Objective-C)

What is the proper syntax for accessing an instance variable in Objective-C?

Assume we have this variable:

@interface thisInterface : UIViewController {
    NSMutableString *aString;
}

@property (nonatomic, retain) NSMutableString *aString;

and that it is synthesized.

When we want to access it, we first would want to allocate and initialize it. Having programmed in Objective-C for about a month now, I've seen two different forms of syntax. I've seen people do simply aString = [[NSMutableString alloc] initWithString:@"hi"], where they allocate the string like that; I've also seen people start it off with self.aString and then they proceed to initialize their ivar. I guess I'm just trying to figure out what is the most proper way of initializing an instance variable, because with the former example, I have received EXC_BAD_ACCESS errors from it. After prepending the self. though, it didn't appear.

Forgive me if this is a duplicate question, but after reading some posts on SO, it's made me curious. I'm trying to learn the proper syntax with Objective-C because I prefer being proper rather than sloppy.

like image 937
SpacePyro Avatar asked Jun 15 '11 15:06

SpacePyro


People also ask

Which is the syntax to access instance variable?

<datatype> <variable_name>; <datatype> <variable_name> = <initializing_value>; public class Employee { public String Name; // Name is an instance variable with public access modifier private int salary ; // salary is an instance variable with private access modifier.

What is instance variable in Obj 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.

Can we access instance variable by using an object?

Instance variables are declared without static keyword. Instance variables can be used only via object reference. Class variables can be used through either class name or object reference.

How do you call an instance method in Objective C?

YourClass *object = [[YourClass alloc] init]; [object someInstanceMethod]; The above is an instance method, because you must create an instance of YourClass (in this case, the object variable) before you can call the method " someInstanceMethod ".


3 Answers

If you have declared a property and @synthesize it in the .m file, you simply set it like this:

self.aString = @"hi"; // or [[NSMutableString alloc] initWithString:@"hi"];

Using self.varName takes advantage of what your property declaration actually does- it handles retention of the new value (since your property has the retain attribute), releasing the old value, etc for you.

If you just do:

aString = someValue;

... you may be leaking the original value that was in aString, since without using self.aString you are accessing the variable directly vs through the property.

like image 146
Steve N Avatar answered Oct 27 '22 00:10

Steve N


Note the difference between self->varName and self.varName

The first is pointer access. The second is property access.

Why is that important? Pointer access is direct. Property access, on the other hand makes use of getters and setters (be they @synthesized or not). Moreover, as a convenience, the @synthesized accessors take care of the memory mangement for you (i.e. when using self.varName = ...;), whereas varName = ...; does only what it says, i.e. the assignment -> (there lies the explanation for EXC_BAD_ACCESS errors you might be getting).

Syntactically, both forms are correct. If you want to better communicate intent, use self->varName when you want to work directly with the pointer and use self.varName when you want to take advantage of the @property convenience.

like image 44
octy Avatar answered Oct 27 '22 00:10

octy


Here are all the possible combinations (I think) OKs and BADs are only correct when aString property has retain attribute:

@property (nonatomic, retain) NSMutableString *aString;

So:

1

aString = [[NSMutableString alloc] init]; //OK: 

This is OK but only in the case aString is not pointing to an invalid object or you will loose a reference to that object and it will leak because you won't be able to reach it to release it.

2

aString = [NSMutableString string]; //BAD

Bad because you are suppose to retain aString (as you declared it that way), you are not retaining it and you will get surely get EXC_BAD_ACCESS in the future

3

aString = [[NSMutableString string] retain]; //OK

Same as the first approach, only good if aString is not pointing to a valid object. However I will use the first though.

4

aString = [[[NSMutableString alloc] init] autorelease];//BAD

Same as the second approach.

5

self.aString = [[NSMutableString alloc] init]; //BAD!!

Bad because you are retaining it twice, hence it will lead to memory leaks

6

self.aString = [[NSMutableString string]; //******GOOD!******

This is probably the safest. It will be retained by the property setter and since you are using the setter any other object that could have been pointed by aString will be released appropriately

7

self.aString = [[NSMutableString string] retain]; //BAD

This is retained twice.

8

self.aString = [[[NSMutableString alloc] init] autorelease];//Ok

This is also OK, but I would use the convenience method instead of this long approach :)

Be wary that the #1 and #3 options are perfectly good if you know what you are doing. In fact I use them much more frequently than #6

like image 35
nacho4d Avatar answered Oct 27 '22 00:10

nacho4d