Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

difference between self.predictions and _predictions in THCrystalBall class

i have this question like what is difference between self.predictions and _predictions in THCrystalBall class. Aren't they both the same. but when i switched _predictions instance variable with self.prediction in THCrystalBall.m class and run the project i got a thread error and when i fixed it and did exactly what was taught in the video, the project did run fine, but now its is showing me the memory usage. I mean it is showing the crystalball is occupying 2.8 MB memory space, but otherwise there are no debug issues.

5 Answers

Stone Preston
Stone Preston
42,016 Points

self.predictions is referring to a property, whereas _predictions is referring to a variable, which you probably dont have defined if you have the property defined.

2.8 MB is very small, just the UIs and the animated images can occupy 2.8 MB easily.

As Stone Preston said, self.predictions refers to a property and _predictions refers to a variable, at least at the high level. They are both pointing to the same variable that is _predictions.

When you use the @property directive, it synthesizes 3 things: a variable, a getter, and a setter. The default variable it synthesizes is named by preceding your property with an underscore (_). The getter and setter methods can then be called with the dot notation, and they are equivalent to the following, which Objective-C codes up for you at compile time:

- (NSString *) predictions {
  return _predictions;
}

// Not synthesized if property is readonly
- (void) setPredictions:(NSString *)yourPredictions {
  _predictions = yourPredictions;
}

When you use the dot notation on the left side of the assignment, the first method, i.e. the setter, is called. For example: self.predictions = @"Boom!"; will be changed to [self setPredictions:@"Boom!"]; by the compiler. When used on the right side or as part of something else, the second method, i.e. the getter is called. For example, NSString * newPrediction = self.prediction; will be translated to NSString * newPrediction = [self prediction];

One reason for why you need getter and setter is that outside your object, you can't access your _predictions variable because it is by default private. Hence you will always need to access it by calling the getter property accessor method or some other methods that returns the variable, e.g. NSString * prediction = yourObject.predictions;

More advanced usages of property includes lazy-initialization, such as including an ad-hoc initialization of the_predictions variable in the getter so that if the getter is called and _predictions is still nil, you initialize it first before returning. Another usage is to include validation code in the setter, so that you only set valid values into the variable when the setter is used.

Thank u so much for responding. I have this code:


if(_predictions==nil){ _predictions=[[NSArray alloc]initWithObjects:@"It is decidedly so",@" All answers are YES", @" Better do it some other time",

                  @" Good time starts now",
                  @" wait for some more time",
                  @" Time is not write",
                  @"Better get started", nil];
}

if i am replacing _predictions with self.prediction then i am getting a thread error, i mean both are referring to same thing right...


As Stone Preston said, self.predictions refers to a property and _predictions refers to a variable, at least at the high level. They are both pointing to the same variable that is _predictions.


please reply

Jo Albright
Jo Albright
5,199 Points

Hi Rashu,

These two items are companions. "self.predictions" calls the methods -(NSArray *)predictions; or -(void)setPredictions:(NSArray *)predictions; depending on which way you use it. And "_predictions" allows you to access the instance variable directly within the instance itself.

Setting :

_predictions = @["Hi"];  
// is directly setting the variable to that initialized array.

self.predictions = @["Hi"]; 
// is calling the method -(void)setPredictions:(NSArray *)predictions; 
// to set _predictions to that initialized array.

Getting :

Using self.predictions over _predictions allows for better control over how the return of _predictions is handled.

NSArray *array = _predictions;  
// is directly getting the variable.

If you get the value of _predictions directly you have to test if it is nil every time you get its value

NSArray *array = self.predictions;  
// is calling the method -(NSArray *)predictions; 
// to get the value of _predictions.

If you use self.predictions you just need to add in the "if nil" test in the -(NSArray *)predictions; once and it now has built in nil checking in one place.

So self.predictions should be used every where within your instance except within the getter and setter methods where the instance variable will be managed.

Note : if you overwrite both of the getter and setter methods or make the property read only, you will need to create a _predictions instance variable.

I hope this was helpful.

Thanks, Jo