Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@property/@synthesize question

I'm going through all of my documentation regarding memory management and I'm a bit confused about something.

When you use @property, it creates getters/setters for the object:

.h: @property (retain, nonatomic) NSString *myString

.m: @synthesize myString

I understand that, but where I get confused is the use of self. I see different syntax in different blogs and books. I've seen:

myString = [NSString alloc] initWithString:@"Hi there"];

or

self.myString = [NSString alloc] initWithString:@"Hi there"];

Then in dealloc I see:

self.myString = nil;

or

[myString release];

or

self.myString = nil;
[myString release];

On this site, someone stated that using self adds another increment to the retain count? Is that true, I haven't seen that anywhere.

Do the automatic getters/setters that are provided autorelease?

Which is the correct way of doing all of this?

Thanks!

like image 282
Buyin Brian Avatar asked May 05 '11 19:05

Buyin Brian


1 Answers

If you are not using the dot syntax you are not using any setter or getter.

The next thing is, it depends on how the property has been declared.

Let's assume something like this:

@property (nonatomic, retain) Article *article;
...
@synthesize article;

Assigning something to article with

self.article = [[Article alloc] init];

will overretain the instance given back by alloc/init and cause a leak. This is because the setter of article will retain it and will release any previous instance for you.

So you could rewrite it as:

self.article = [[[Article alloc] init] autorelease];

Doing this

article = [[Article alloc] init]; 

is also ok, but could involve a leak as article may hold a reference to an instance already. So freeing the value beforehand would be needed:

[article release];
article = [[Article alloc] init]; 

Freeing memory could be done with

[article release];

or with

self.article = nil;

The first one does access the field directly, no setters/getters involved. The second one sets nil to the field by using a setter. Which will release the current instance, if there is one before setting it to nil.

This construct

self.myString = nil; 
[myString release];

is just too much, it actually sends release to nil, which is harmless but also needless.

You just have to mentally map hat using the dot syntax is using accessor methods:

self.article = newArticle
// is
[self setArticle:newArticle];

and

myArticle = self.article;
// is
myArticle = [self article];

Some suggestions on reading, all official documents by Apple:

The Objective-C Programming Language

  • Dot Syntax
  • Declared Properties

Memory Management Programming Guide

  • Object Ownership and Disposal
  • Using Accessor Methods
like image 142
Nick Weaver Avatar answered Sep 20 '22 13:09

Nick Weaver