Question

I prefer to use properties for classes in Objective-C like this (which seems standard in newer Xcode versions):

/* MyClass.h */
@interface MyClass : NSObject;
@property (nonatomic, strong) NSArray *myArray;
@end;


/* MyClass.m */
#import MyClass.h

@implementation
@synthesize myArray = _myArray;

- (void)anyMethod {
    self.myArray = // do something
}

@end

However in some github repositories on the web I found different ways of using properties, e.g.:

/* MyClass.h */
@interface MyClass : NSObject {
    NSArray *myArray;
}

// sometimes the @property is used here too

@end;


/* MyClass.m */
#import MyClass.h

@implementation

- (void)anyMethod {
    _myArray = // do something
}

@end

What exactly is the difference between those ways? I read it has to do something with access of instance variables. But why do some people declare the variables in @interface section and do not (or do sometimes) use @property?

Was it helpful?

Solution 3

{
 NSArray *myArray;
}

the above thing is called member Variables it can't be accessed outside the class.(Important point) (unless you provide custom getters and setters)

if you make a @property then the variable an be read inside the class as well as outside the class..so the setters and getters are generated for you..automatically

then declaring the same as a member variable isn't required..

It is done to increase Readability and it's also considered a significant component of memory management strategy.

as you talking about private property so fot that

A. If you want a completely private variable. Don't give it a property.

B. If you want a readonly variable that is accessible external from the encapsulation of the class, use a combination of the global variable and the property:

OTHER TIPS

There are several aspects to be considered here, some of them are already mentioned.

First of all, the underscore is just a legal character and part of the name. It is more or less just a convention that the local iVar _foo corresponds to the property foo. That is always the case when

  • You have them autosynthezised. (no @synthesize statement) Then the iVar is generated automatically with a leading underscore. (in newer versions of Objective C)
  • You intentionally declare the iVar _foo and extend the @synthesize statement in that way that it refers to _foo when it is named foo. You could as well declare the property foo and the ivar bar and link them in the @synthezise or in custom getters. This were just far away from any convention and therefore not generally recomended. Example: @synthesize foo = _foo;
  • You provide custom getters and setters and access the property. Again, you could link any iVar with the property or even set a number of them in response to the input etc. pp.

The property foo corresponds to the ivar foo when

  • You use @synthezise without providing the name of the ivar. Just @synthesize foo; (I think, depending on the version of ojective-c, that works with or without explizit declaration of the ivar foo, but I would not sign that in blood)

In general I recommend to stick to the underscore pattern, although I don't do that always myself. The advantage is that the separation between the ivar and the property is more visible to the programmer which helps avoiding mistakes. Especially local parameters of the same name (quite common) would not hide the ivar. Example with foo:

foo = @1; //This refers to the iVar foo. 
self.foo = @1; //This calls the setter. 
[self setFoo:@1]; //This calls the setter. 
someVar = [self foo]; // This calls the getter. 
foo = foo; // This would not work assuming that foo is a local parameter of the method.
self->foo = foo // This is not good style but a workaround for the line above in that situation. This accesses the ivar directly on the left side of the equation, not its setter.
self.foo = foo; // This is fine when foo is the local parameter.

The same with _foo, where it is just more clear to the programmer:

_foo = @1; //This refers to the iVar _foo.  
self.foo = @1; //This calls the setter. 
[self setFoo:@1]; //This calls the setter. 
someVar = [self foo]; // This calls the getter. 
_foo = foo; // This would work nicely assuming that foo is a local parameter of the method.
self->_foo = foo // No need for doing that. It is rather C style anyway and not that common in Obj-C.
self.foo = foo; // This, too, is fine when foo is the local parameter. Clearly uses the setter.

the "_varName" refers to the actual variable stored in memory. by using "self.varName..." you are simply using the accessors to "get" & "set" the variable using the dot syntax convention. so by doing

self.varName = someValue;

or

[self setVarName:someValue];

in reality you are calling a method

- (void)setVarName:(ObjectType *)varName

this is just a classic "setter" method and is what is responsible for setting the value of that variable. this would be like going into a restaurant and putting in your order with a waiter / waitress, vs going into the kitchen and doing it yourself.

typically the latter is frowned upon and recommended you use the accessor methods to set and get the value using "self...". this is because the accessor methods will usually be setup in such a way to "verify" that the appropriate data is being stored. this is more so the case with custom accessors where other tasks are done while getting or setting the value. there are other reasons but "protection" is really the main point.

when you do

_varName = someValue; 

the setter method is not used, and the variable is directly changed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top