iPhone Dev - Using a getter in the same class - iphone

(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!!

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.

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.

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

Related

Internal properties versus ivars

When I need a private object I currently use properties, like so:
// Class extension in .m file
#interface MyClass()
#property (strong, nonatomic) NSArray* myInternalArray;
#end
self.myInternalArray = something;
Alternatively you can do this:
#implementation MyClass {
NSArray* _myInternalArray;
}
_myInternalArray = something;
Without a custom setter or getter the two are equivalent. What is the best practice for internal variables? Are there any advantages of one method over the other?
While some may argue that the choice is a matter of preference, and they do have a point, there is a very good reason that most modern languages support properties and make them easier and easier to code.
The introduction of ARC does not significantly reduce the value of properties. It all comes down to this - in a property you have encapsulated the use of a variable. That encapsulation is invaluable when needed, and not much overhead when it is not.
For example (off of the top of my head) Suppose you discovered that you needed to validate the value before saving it. If you were using an iVar, you would have to ensure that anywhere that iVar was used, you had a call the validation code before you allowed it's value to be changed. With a property, you would only need to override setIVarName: and put the validation there. One could argue that one is just as easy as the other - and that may be true in many cases, but there is one handicap with the iVar here - you cannot ensure that future changes (by you or other coders) will insert the validation before the iVar is changed. Using a property here does have that assurance.
Personally, I use properties over iVars where ever possible.
I'd say that the advantage of properties is that you would use setters, and that setters can evolve independently of the code that call them. For instance, you could decide that setting a property would now trigger setNeedsLayout. By using properties from the start, you would have no need to refactor existing code.
This pattern fits very well in Cocoa/iOS APIs, where you don't have to ask system objects to do anything after having changed their properties: setters ensure internal and UI consistency right away.
The fact that properties are private should not make us implement them as second-class properties, what do you think?

should I always use self.classvariable?

When coding my iPhone app. Is it always a good practice when setting or getting values to use self? I seem to forget half of the time and recently have been tracking down a bug I believe is related to this.
Should I ALWAYS use self or are there cases when it's not necessary or would cause problems?
Edit:
Here's an example of what I'm doing in the code
else if([CellIdentifier isEqualToString:#"Linked Item"]) {
linkedItemLabel = [[UILabel alloc] initWithFrame:CGRectMake(120, 5, 160, 34)];
linkedItemLabel.adjustsFontSizeToFitWidth = YES;
linkedItemLabel.textColor = [UIColor blackColor];
linkedItemLabel.font = [UIFont systemFontOfSize:17.0];
linkedItemLabel.text = [storedValuesMutableArray objectAtIndex:7];
linkedItemLabel.backgroundColor = [UIColor clearColor];
linkedItemLabel.textAlignment = UITextAlignmentRight;
[cell addSubview:linkedItemLabel];}
This is part of the code that sets up my tableviewcells for a form that needs to be filled. Should I be using self.linkedItemLabel or is this fine?
You have to understand that using self.property is a method call (getter or setter method), not a simple assignment.
You should use the ivar directly only inside the setter or getter body.
Reasons:
1/ Properties are meant to shield you from the retain-release hell. Let's imagine you have a "assign" property, you are using the ivar directly and then you decide changing it to "retain". What you get is a bug difficult to find.
2/ Setters and getters can do additional functionality (e.g. setter can add/remove observers to an object) or logging. If you are using the ivar directly you miss this special functionality.
3/ Setters and getters can be overriden in a subclass.
In small projects you can probably avoid most problems even if you are using ivars directly but on big projects, programmed by a team, you should use only self.property to reduce bugs and improve code maintainability.
It's also a good idea to give your ivar a different name (like property_ or _property because you'll notice when you are using it without self..
If you are not writing a high performance game or mathematic algorithms, don't worry about worse performance when using self.property.
It depends on the case, if you are just using #synthesize to auto-generate the getters, then it would not cause any problems on the getters. Although common OO practices tell you to use encapsulation, you will notice pretty much all apple sample code accesses the ivar directly.
Another common practice to refer to the ivar without using self is to synthesize like this:
#synthesize myVar=_myVar
and use _myVar when referring to that variable.
It would only cause a problem, if you implemented something in your getter, instead of using #synthesize.
As for the setters, it isn't exactly a problem, but you just have to keep in mind that the properties for that ivar will only be applied if you do self.myIvar as opposed to accessing the iVar directly, so for example a property declared as (retain), will only be retained if you do self.myIvar = newValue as opposed to myIvar = newValue.
The issue arises with properties. if you do not add the self., then you end up assigning to the variable directly, missing out on the property attributes e.g. retain, assign and thus messing up reference counting for the item, and thus causing potential memory leaks.
You should use self, unless you have an explicit reason not to.
You must use it with clever and clear understanding.
If you're using so-called dot-syntax (i.e. self.myVariable) it means you're calling a getter or setter of the property, which is actually a selector sending to an object instance, which is pretty heavy within Objective-C run-time. So, if you need just a value of your var - you can call it once and reuse saved state or call directly to i-var (if permissions allow).
Call for getters/setters when you really need them.

Changing fetchedResultsController_ to protected from private

The code generated by Xcode when creating a navigation based application which uses core data declares fetchedResultsController_ as private
#private
NSFetchedResultsController *fetchedResultsController_;
NSManagedObjectContext *managedObjectContext_;
Some one please explain whether there is a reason to declare it as private?
I intends to create a CommontableViewController and subclass it to use in a tab bar application with five tabs. Is there any issues if I remove the private declaration and make it protected. My compiler does not give any warning, but I am worried about the data integrity.
I believe the template also adds #property declarations for those two variables; is that correct? If so, your subclasses should use self.fetchedResultsController and self.managedObjectContext instead of accessing the variables directly. That way you can maintain encapsulation and keep the variables private.
The point of having them be private is that only the superclass should be responsible for setting up the storage for those objects; subclasses can just use the getter methods when they want to use them. Of course, nothing would burst into flame if you decided to make them protected, but I don't think there's a real need to.

What is the meaning of the console message: "snarfed from ivar layout..."?

I have a console message that appears to be triggered by apparently unrelated events.
The message states:
snarfed from ivar layout: [propertyName] = [constantString]
Where [propertyName] is the name of a property to which I set the value of a string constant [constantString].
What causes this message and what does it means?
I also ran into this issue recently. I was able to fix my specific issue, but I don't think that is exactly what the questioners are running into, since my issue was only being exposed in VoiceOver mode. As such, I'll offer thoughts on what I think is generally occurring and then I'll speak to my specific issue.
As for the general issue, I think that the Apple Framework is deciding to look through all of the ivars of a particular class in order to extract some information that it wants, but that is not provided by other parts of the UI element. This seems a little bizarre to me, but that is what I encountered.
So, to continue with the general case, and in answer to the initial question. If you're like me, then your property name is probably the same as your ivar. Try explicitly defining a getter method for that property. Then, set a breakpoint within that getter if you will be returning a non-nil value. Look at the stacktrace and that should tell you which piece of the apple frameworks is deciding to loop through your ivar layout in order to get the information it wants. (If you're not using the the same name for your property and ivar, then just define a property and getter with the ivar name and do the same thing with the breakpoint.)
My specific case was for a Custom Table Cell (like one of the commenters). In that cell,I had a property that was the same name as its ivar. I also had an explicitly defined getter for that property. I also referenced that custom table cell from the Nib file. So, it looked something like this:
class CustomTableViewCell:UITableViewCell
{
NSString *s ;
}
#property(nonatomic,retain) NSString *s ;
and in the implementation:
#synthesize s ;
-(NSString *)s
{
if( !s )
return self.reuseIdentifer ;
return s ;
}
I put a breakpoint in the return self.reuseIdentifier line,and that showed me a stacktrace from the Accessibility functions. The stacktrace showed my method being called by an Apple internal method that was looping through all of my ivars looking for something to use as the accessibilityLabel for my table cell. The name of the selector is '_accessibilityRetrieveTableViewIvarsText'.
To make matter worse, in my case, this was not just a debugger issue, it was messing up my Accessibility interface by using the wrong thing as the accessibilityLabel.
I came up with 3 fixes for my specific problem:
1) I added a value for the accessibilityLabel for the table cell inside the Nib. This satisfied the Apple framework to the point where it did not go searching through my ivars. This was not the solution I went with, however, because I did not want a static accessibility label.
2) I subclassed my CustomTableViewCell with an empty implementation and interface, and I used that as my Table cell class inside the Nib. This solved the problem because the Apple Framework looped through that class's ivars, of which there were none, and there weren't any values to 'snarf'. I did not use that solution either, but it might be the best one because it keeps Apple's frameworks from inspecting my ivars.
3) The solution I decided on was to make my ivar private and to define the property with a different name. That seems to be the standard way that a lot of folks use properties. This is what it looks like:
class CustomTableViewCell:UITableViewCell
{
#private
NSString *_s ;
}
#property(nonatomic,retain) NSString *s ;
and in the implementation:
#synthesize s = _s ;
-(NSString *)s
{
if( !_s )
return self.reuseIdentifer ;
return _s ;
}
This fixed the problem because nil is returned when Apple inspects the ivar, and, thus, nothing is 'snarfed'. I'm still not sure whether this or #2 is more appropriate.
"snarfed from ivar" basically autofills your accessibilityLabel. If you do that yourself, the message goes away, as there is no more need for sneeking into your UITableViewCell.
For future reference. The message is logged by the accessibility framework, which apparently looks through an UIView ivars for strings.
If you have a custom subclass you can define the custom attributes as specified in the following link:
Accessibility Programming Guide
Alternatively you can make the view subclass not accessible:
- (BOOL)isAccessibilityElement
{
return NO;
}
However, note:
If your application contains a custom individual view with which users need to interact, you must make the view accessible.

Using self in method call

When using property/synthesize for a UITableView, UIButton, etc should self be included in the method call on that variable? Using UITableView as an example is there a difference between [self.myTableView visibleCells] and [myTableView visibleCells]? Or say [self.myImage setImage:...] and [myImage setImage:...]?
I've seen Apple code that does use self (Bubble Level) and examples in the book Beginning iPhone Development that do not use self. I'd like to understand this better, especially since using self in my UIScrollView method calls has caused erratic/buggy scrolling behavior. Thanks.
Using self.myTableView is another way of saying [self myTableView] (it can also be [self setMyTableView:...]; if used in an assignation statement). In other words, you're executing a method.
Using myTableView accesses the instance variable directly.
Personally, I generally prefer using the former method, since it usually frees me from manually managing memory and gives me the benefit of KVO notifications. However, there is the miniscule overhead of the extra method call, which you may wish to avoid.
Which style you choose to use is up to you, and each way has its benefits and disadvantages.
The difference comes down to how you define the property. For example, say you have the following:
#interface MyObject : NSObject {
NSObject *memberVariable;
}
#property (nonatomic, retain) NSObject *memberVariable;
#end
#implementation MyObject
#synthesize memberVariable;
#end
Specifying (nonatomic, retain) actually tells #synthesize how to create the getter and setter methods. Specifying retain causes the setter method to call retain on objects I pass to it. So, self.memberVariable = someOtherObject is equivalent to memberVariable = [someOtherObject retain];
This is also why you should never do self.memberVariable = [[NSObject alloc] init]; if you've specified retain in the property definition. alloc initializes the retain count to 1, passing the object to the setter method increases the retain count to 2.
This comes down to whether or not your accessor methods have custom behavior, in which case you'd always want the accessors called even from within the class, and whether you want to make sure KVO notifications are generated. If you're using stock accessors (e.g., synthesized) and it won't affect anything to access the instance variable directly from within the class, you're saving yourself a method call.