Saturday, July 21, 2012

Self keyword and setter functions

Let me begin this post with an example:
Consider this variable:

NSArray * myArray;
@property(nonatomic, retain) NSArray * myArray;


The above lines of code causes the compiler to generate a default setter function for the myArray variable which retains the variable.

The compiler generated setter function would like something like:

(void)setMyArray:(NSArray *)tmpMyArray{
  [tmpMyArray retain];
  [myArray release];
  myArray = tmpMyArray;
}


Observe that the setter function releases the current myArray before assigning a new value to it. That is why, when we set a value to a variable we should always ensure that we use the self.member syntax. 

// The following line invokes the setter function to set this value
self.myArray = anArray; 

// The following line does not invoke the setter function and thus causes a memory leak because release is not called on the previous value of myArray.
myArray = anArray;

Another thing to be remembered is, if we are defining a custom setter function, we MUST implement all the steps that a compiler-generated setter would contain.



Beware of the self keyword within setter functions



This is applicable only if you are writing your own custom setter function. The following example summarizes it all:

- (void)setMyArray:(NSArray*)tmpArray{

  // First, retain the value
  [tmpArray retain];

  // Next, release the previous value
  [myArray release];


  // Now here is where you need to be careful
  // Set the value
 
 // WRONG: Don't use self.member within a setter function 
  // self.myArray = tmpArray


  // RIGHT: Always call the member variable directly within the   setter function
   myArray = tmpArray
}


Now for those of you who are still curious and wondering why you shouldn't use the self.member syntax within the setter function, here is the reason.

Using self.member syntax invokes the setter function of that variable, so if you use the self.member syntax within the setter function the setter function will be called recursively and your program will be in an infinite loop.

No comments:

Post a Comment