RunLoop
RunLoop

Reputation: 20376

Basic questions re Objective-C property syntax

I have a few basic questions regarding the syntax and usage of properties in Objective C:

Assume the following declaration in the header:

@interface TestObject : NSObject {

    NSArray *myArray;
}

@property (nonatomic, retain) NSArray *myArray;

In the implementation, can I:

  1. List item
  2. Use myArray and self.myArray interchangeably for setting and getting purposes?
  3. Is self.myArray = nil equivalent to [myArray release]?
    If so, Is there ever a reason to use self.myArray = nil rather than [myArray release]?

Upvotes: 4

Views: 283

Answers (3)

Steven Canfield
Steven Canfield

Reputation: 7332

Both existing answers are wrong.

@synthesize generates setters and getters that look like this:

- (void)setMyArray:(NSArray*)array {
    if( myArray != array ) {
        [myArray release];
        myArray = [array retain];
    }
}

- (NSArray*)myArray {
    return myArray;
}

(Note, they aren't exactly like this, and differ if you specify copy, or other attributes, but that's the basic formula). Now we can see that self.myArray = nil; WILL release the old array. self.myArray and myArray aren't interchangeable for setting purposes. Moreover, self.myArray = nil; will continue to work in a garbage collected world.

As Dave Delong points out, self.myArray = nil will notify anyone observing myArray of the changed value, which could be a problem if you do this in your dealloc method. To avoid this case your dealloc would look something like:

- (void)dealloc {
    [myArray release]; myArray = nil;
    [super dealloc];
}

(note myArray = nil; is a stylistic choice here.)

Upvotes: 4

andyvn22
andyvn22

Reputation: 14824

  1. myArray and self.myArray are actually different. myArray is accessing the variable directly, whereas self.myArray (which is equivalent to [self myArray]) is calling an accessor method. Most people agree that you should use self.myArray (or [self myArray]) all the time, and never use myArray directly. This is because the accessor might have side effects; for example, KVO won't work if you set your variable directly, and memory management won't be handled for you.

  2. Your property is declared with retain, so self.myArray = anArray (which is the same as [self setMyArray:anArray]) does the following:

    1. Retain anArray, which will soon be the new myArray.
    2. Release the old myArray, which will soon no longer be myArray.
    3. Change the pointer myArray so it now points to anArray.

Therefore, when you do self.myArray = nil, one of the steps (#2) is indeed release the old array. (And since the new one is nil, we don't have to worry about its memory management, even though we retained it.) So yes, self.myArray = nil is a valid way of releasing myArray.

HOWEVER, if you're talking about releasing myArray in dealloc, it's generally a good idea to use [myArray release], because calling self.myArray = nil will have side effects if any other objects are observing myArray through KVO. So while it does follow memory management standards, it's not a good idea to write your dealloc method using self.myArray = nil.

Upvotes: 5

Scott
Scott

Reputation: 4200

To setup setters/getters you'd have to implement those in main as:

+ (NSArray*) myArray {
return myArray;
}

+ (void) setMyArray:(NSArray*)input{
myArray = input;
}

Upvotes: -3

Related Questions