1

I'm a bit confused when it comes to synthesize properties.

Lets say that I have this property in my *.h file.

@property (nonatomic, retain) NSString *aString;

And in my *.m file I synthesize it. @synthesize aString;

I know that the compiler will generate setters and getters when Im using synthesize. But how does these setters and getters look like?

And when I shall give aString a value, which ways are correct?

self.aString = @"My New String"; // This will use the setter?
aString = @"My new String"; //This will not use the setter and retain the string, right?
aString = [@"My new string" retain]; //This will not use the setter, but it will retain the string ?
[self setAString:@"My new string"]; //This will also use the setter?

Thanks in advance!

magnus
  • 33
  • 3

4 Answers4

5

When you do:

@property (nonatomic, retain) NSString *aString;

...followed by:

@synthesize aString;

...your class gets three basic things:

  1. An instance-variable called aString that you can reference directly within your class.
  2. A getter function with a signature - (NSString*) aString; that returns the instance variable.
  3. A setter function with a signature - (void) setAString: (NSString*) value; that retains the parameter that is passed in and assigns it to the instance variable (and releases any previously retained value, if one exists);

Implementation-wise, these generated methods and fields might look like:

//in the .h file
@interface MyClass {
    NSString* aString;
}

- (NSString*) aString;
- (void) setAString: (NSString*) value;

@end


//in the .m file
@implementation MyClass

- (NSString*) aString {
    return aString;
}

- (void) setAString: (NSString*) value {
    if (aString != value) {
        [aString release];
        aString = [value retain];
    }
}

@end

So to answer the rest of your questions:

self.aString = @"My New String"; // This will use the setter?  Yes, and it will retain the string.
aString = @"My new String"; //This will not use the setter and retain the string, right?  Right.
aString = [@"My new string" retain]; //This will not use the setter, but it will retain the string?  Right again.
[self setAString:@"My new string"]; //This will also use the setter?  Yep.

As for which are correct, they all are, depending upon what you want and assuming that you understand how the behavior differs between using each one, particularly with respect to releasing/retaining property values. For instance, this code will leak memory:

self.aString = @"Value 1";  //go through the setter, which retains the string
aString = @"Value 2";        //bypass the setter, the 'Value 1' string will not be released

...and this equivalent code will not:

self.aString = @"Value 1";  //go through the setter, which retains the string
self.aString = @"Value 2";  //go through the setter again to release the first string
aroth
  • 54,026
  • 20
  • 135
  • 176
  • Very good answer, learned some new things about obj-c programming that might fix some of my bugs! – Dan F May 03 '11 at 13:30
  • 1
    That setter should check that `aString != value` or the retain count could accidentally drop to 0. `if (aString != value) { [aString release]; aString = [value retain]; }` – albertamg May 03 '11 at 13:38
  • Thanks! That was pretty much what I though. But it's nice to get it confirmed:) – magnus May 03 '11 at 14:02
2

The getter and setter are used when you use "dot" syntax (e.g. self.aString, self.aString = ...) or message syntax (e.g. [self aString], [self setAString:...]).

Assigning directly to the backing variable (in your case somewhat confusingly named aString) will not use the synthesized methods. To change the name of your backing variable, declare it in your interface as a private variable (in the .h):

NSString *aString_;

and then synthesize it like this:

@synthesize aString = aString_;

This will use aString_ as the backing variable for your property, so you can directly reference the storage for your property by using aString_.

kevboh
  • 5,207
  • 5
  • 38
  • 54
0

Regarding what the code would look like, take a look at this question.

Regarding which of those lines use the getters/setters: only the 1st and 4th do.

self.aString = @"My New String";
[self setAString:@"My new string"];
Community
  • 1
  • 1
André Morujão
  • 6,963
  • 6
  • 31
  • 41
0

Following are correct setter.

self.aString = @"My New String";
[self setAString:@"My new string"];
Chetan Bhalara
  • 10,326
  • 6
  • 32
  • 51