views:

483

answers:

3

(Just to let you now, I'm learning to develop for iPhone with a book I got called Beginning iPhone 3 Development: Exploring the SDK, and I do not use Interface builder) Is there ever a reason to use the getter in the same class, when a private member is visible? Like in Foo.h, having

NSObject *myObj;
...
@property (nonatomic, retain)NSObject *myObj;

and then in Foo.m, accessing the member myObj using self.myObj (or [self myObj]) ? Because in my book, Here is what it tells you to write in one of the apps (its checking if a UIViewController member's view is in the superview) :

if(self.yellowViewController.view.superview == nil) {

(notice the self.yellowViewController...) Is there actually a reason for this? If there isn't one idea I have is maybe because the member blueViewController is of class BlueViewController, so I think if there is no reason it may be to not cause confusion. So is there anytime where using the getter in the same class is needed?

Thanks!!

+1  A: 

Yes, accessing your ivars through a getter than directly is a good thing to do.

As an example: One of the normal design patters in Cocoa (especially on the phone, where resources are very limited) is called lazy loading.

Summed up, it means don't load a resource until you need it.

Ideally, you would want to place code in your getter that would check to see if the resource being requested is loaded, and if not, load it. Accessing the ivar directly would just return nil. The alternative would be to initialize all of the ivars when your parent class is init'ed, thereby potentially wasting resources to store data that may or may not be needed.

This also allows you to potentially place resources that could potentially be retrieved again in your applicationDidReceiveMemoryWarning: methods and dump them when resources got tight, because they will be loaded again on demand when needed.

mmc
Yes, this part of the book does use lazy loading.. but how did you know that, and you didn't answer my question..
Mk12
I thought I did. "So is there anytime where using the getter in the same class is needed?" Answer - Yes, when you are using lazy loading (which is a good thing to do).
mmc
Ok. What Does ivar mean? Is lazy loading the only time to access members throug getters? Can you show me how to make a getter for lazy-loading?
Mk12
Please someone tell how to make a lazy-loading getter, and is lazy loading the only reason to use self.member, and what does ivar mean?Thanks!
Mk12
ivar = instance variable, and the easiest way to get the getters written appropriately is to let the compiler write them for you, using @properties and @synthesize
mmc
Also note that using the getter will be slower as it actually calls a method. In long loops it makes sense to call the getter once before the loop body begins and reuse the value rather than calling the getter multiple times.
rpetrich
I only do that (use getter only first time referenced in a method) when its lazy-loaded, using var directly instead of using getter (which just returns the ivar) is premature optimization, IMO. Also, if you always use the getter, you can change the getter later to make the ivar calculated or something.
Mk12
+2  A: 

Lazy loading getter:

- (UIImageView*) getImageView
{
    if (!imageView)
    {
        imageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @"blah.png"]]; // just an example
    }
    return imageView;
}

Depending on how imageView is defined (copy, assign, retain) you will need to modify the actual assignment, but this is what is meant by lazy loading.

Amagrammer
Thanks! A few questions: Is !imageView the same as imageView == nil? And with this imageView (for an example) would I use self.imageView evreywhere? And do you know what ivar means? Thanks again!
Mk12
When accessed as a boolean, pointers are treated as false when NULL and true with any other value. Thus !imageView is equivalent to (imageView == nil)
rpetrich
Yes. I have gone to that !imageView notation because I am trying hard to avoid falling into a mistake I made early in my iPhone development. (I was testing BOOLs against == YES or == NO -- not recommended, it turns out.) imageView == nil is really better from a self-documenting point of view.
Amagrammer
Final note: You might think that the extra overhead of checking whether imageView is non-nil is a big price to pay. But particularly on the iPhone, CPU cycles are relatively inexpensive, and memory is very limited. Picture an NSArray of a thousand or so data objects, each of which has an image associated with it, displayed in some sort of table. Picture the memory requirement (and CPU too) of loading ALL of those images, when you won't use them unless they are scrolled in. (You may want to create the objects so that you can get minimal information for sorting, for example.)
Amagrammer
+1  A: 

A few reasons to use the self.ivar getter syntax instead of directly accessing the instance variable:

  • Lazy-loading properties, as others have mentioned
  • Subclasses may want to override the property and have the superclass respect that
  • If you use atomic properties, the only correct way to access the property is through the getter
John Calsbeek
So basically if all self.ivar is doing is returning ivar, then there's no difference so you might as well just write ivar.
Mk12
Right; except you can't actually know that for certain when you write the class, as the class may be overridden later without your knowledge. Of course, if this is just your project, you can promise yourself to never do that.
John Calsbeek