Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjectiveC ivars or @property

Working on iPhone, after a lot of headache and memory problems I just realized from other examples that we do not need to necessarly create @properties for each instance variable we define in header file. And actually I found out ivars easy to just allocate and release it after I use anywhere in the class, for @properties I have to use autorealese or I have serious problems and becareful how I allocate..

For instance for objects below, @properties(retain/copy..) is not used in headers in many examples;

{
NSURLConnection *connection;
NSMutableData *xmlData;
NsMutableString *string
} 

But for some strings or object types @properties is used, I know that when we set @property cocoa creates some setters getters which are handling the relasing and retaining of the objects. But seems like as for xmlData or connection instance variables we do not need that and they do their job like this.

Are there some reference guidelines I can keep in mind on deciding whether or not to create @property's or just use simple ivars?

My only problem when using properties is not becuase I am lazy to define it, but when I carefully allocate and init them in code, I have to use autorelase and dont feel like I have the control when to release reset and allocate it again, and it gives me one more thing to worry about while and when and how should I release, reset it. I find ivars I can alloc and release anytime once anywhere easily without worrying about anything..or I am missing other things here.

Tnx

like image 901
Spring Avatar asked Aug 04 '11 13:08

Spring


2 Answers

There seem to still be some misconceptions flying around about properties.

that we do not need to necessarly create @properties for each instance variable we define in header file

Correct. You can use private instance variables directly in your implementation file. However, since synthesized properties come with free memory management, you might as well take advantage. My rule of thumb is to use the ivar directly until the first time I find myself writing:

[ivar release];
ivar = [newIvar retain];

As Sam says, there is already a potential bug there if iVar == newIVar. This is the point at which I switch from using ivars directly to creating a property. However, I put the declaration of the new property in a class extension in the implementation file. This means that the property is officially not part of the public interface (and will cause compiler warnings if used accidentally).

when we set @property cocoa creates some setters getters which are handling the relasing and retaining of the objects.

Actually, no. The @property just declares a property. In order to automatically generate the getter and setter, you need to @synthesize it. You could, alternatively write your own getters and setter which do not even have to reference a real ivar.

Technically, you should not use the property in the init or dealloc methods because a subclass might have overridden them or (in dealloc) you might set off a KVO notification.


From Sam's answer and comments

If you want a property regardless, you could use a private interface at the top of the implementation file

As I say above, private categories have sort of been obsoleted by class extensions (which is near enough the same thing but allows you to put the implementation of the methods in the main class implementation).

If you want the benefits of using dot notation shorthand

Some of us would argue that there are no benefits to dot notation. It's a gratuitous and needless pollution of the struct member syntax. However, dot notation has no relation to @property declarations. You can use dot notation for any accessors no matter how they were declared, provided they adhere to the pattern -foo and and -setFoo:

like image 100
JeremyP Avatar answered Sep 22 '22 10:09

JeremyP


Create properties only for variables that need to be accessed from outside the class. Any class variables that are used internally need not have getters/setters defined.

Generally speaking an abundance of properties indicates high coupling and poor encapsulation. You should restrict what variables your class exposes in the interface.

EDITED to respond to comment:

Using properties over direct access may be preferred because it gives you easy memory management.. for example:

// interface
@property (retain) Object *someVar;     

// implementation
self.someVar = otherVar;

is the same as

// implementation
if (_someVar != othervar)
{
    [_someVar release]
    _someVar = [otherVar retain];
}

However you should not needlessly expose vars in your interface because it opens the class up for people to use in the wrong way.

If you want a property regardless, you could use a private interface at the top of the implementation file

@interface TheClass(Private)
    // private stuff
@end
like image 43
Sam Avatar answered Sep 21 '22 10:09

Sam