Require some understanding for Singleton Pattern - iphone

I am going to paste a code here and had a question regarding that which I wanted to understand merely, based on the logical way.
#interface MySingleton : NSObject {
NSString *enteredCode;
}
#property (nonatomic, retain) NSString *enteredCode;
#end
#synthesize enteredCode;
-(void) addInput:(NSString *) input
{
self.enteredCode = [self.enteredCode stringByAppendingString:input];
}
- (void)dealloc {
[enteredCode release];
}
#end
In my code, if I utilize "self.enteredCode = [self.enteredCode stringByAppendingString:input];"
everything works fine but "enteredCode = [self.enteredCode stringByAppendingString:input];" it gets exc_bad_access, and I am just wondering why this case be?
I am just trying to understand what difference really does it makes without having self there?
Thanks.

This is not to do with singletons. When you do self.enteredCode you are going through the property which is set to 'retain'. The stringByAppendingString method is a convenience method with returns an autoreleased object to you, meaning that it will be released at some point on the next run loop. You need to retain this value to stop it being released, which is fine when you assign it through the property as it is properly retained by you and you can use it as you like.
When you reference the variable directory (without the self.) you bypass this and as such you don't ever retain the value, the value is subsequently released and you reference bad memory and BOOOOOOOOM, bad access.

when you call self.enteredCode = XXX it will call [self setEnteredCode:XXX]. Since you are using a retain property this will release the old value of enteredCode, and retain the new value.
if you directly manipulate the enteredCode variable you will have memleaks and crashes because it will try to release something that is not retained later.

If I understand correctly, self.enteredCode works but enteredCode fails.
If that's the case then I believe it's because you're bypassing the property and setting the iVar directly. That means you're assigned an auto released object and bypassing the retain mechanism.
Consider using something like _enteredCode for your iVars do it's clearer in your code when you're bypassing properties.

Related

Releasing a (nonatomic, retain) synthetized property

My question looks like a dozen ones about releasing properties, but I can't find the exact answer i'm searching for.
When a property is declared with retain :
#property (nonatomic, retain) NSString * myString;
then
#synthesize myString;
It generates getters and setters with retaining and releasing operations. Okay.
Of course, property must be released in dealloc.
-(void)dealloc {
[myString release];
myString = nil;
[super dealloc];
}
So that's clean.
But what if i never use myString ? Is it pre-initialised ? My opinion is the myString retain-count would be 0. But releasing myString in dealloc would decrease it and make the application crash ? But it does not crash !
Is a cleaner way to release it like ?
if(myString != nil) {
[myString release];
myString = nil;
}
The key thing you are missing is that you can send messages to nil. So no, your latter approach is not cleaner, just unnecessary.
If you never use myString, it's not initialized to anything. It remains nil. When you release it, you are effectively doing [nil release] - which doesn't actually do anything. Hence no crash.
There is no need to check wether it is nil.
If you send the release to a nil object nothing happens, so why check.
When an instance of object is created the property will be set to nil unless you initialize it in any of the init methods.
It not the same with variables you create in a method, they could point to invalid memory. Thus setting these to nil is the safe way. This is not needed for properties.
You can send release messages to nil objects in objective-c this way nothing happens. I mean the application wont crash. The idea behind setting objects to nil comes handy when an object is used in multithreaded environment since with multiple threads you can't always guarantee that an instance variable will only be read before it's released.
if you are using #property(retain/copy) & #synthesize there is no need to check for nil. It won't crash or throw EXC_BAD_ACCESS.
Otherwise, if you are not using that, you have to check whether the variable is nil or not, or it will crash if the variable is nil.

Retaining an Assigned Instance Variable Property

I have a property that has (nonatomic, assign) as attributes.
In a method, I then am retaining that variable then releasing it a line after.
Static analyzer is giving warning that incorrect decrement of the reference count of object....
Can I not do this
#property (nonatomic, assign) Class *iVar;
[self.iVar retain];
[self.iVar removeFromSuperview];
[self insertSubview:self.iVar atIndex:self.iVar.index];
[self.iVar release];
Since the retain and release both happen in the same method, you might want to copy the property to a local variable and then work with that:
UIView *someView = self.interestingView;
[someView retain];
//...do some stuff...
[someView release];
That at least provides some protection in case the "some stuff" part happens to modify self.interestingView. And it'll probably satisfy the static analyzer, too.
In general, I would avoid retaining/releasing variables that back properties outside the accessors for those properties, except for a few well defined situations such as -dealloc. Similarly, avoid directly retaining/releasing the result of a property access, as in [self.foo retain]. If that property is changed before you get to the release, you end up with both a leak and, later, an over-release.
The trouble is that you're not working with a variable; you're working with the result of a property accessor. Each time you access the property, the static analyzer applies the normal memory management rules for an object returned from a method — namely, you shouldn't be releasing it. If you change it to use an actual local or instance variable, the warning will go away.
I just tested a similar example,
You will appease the static analyzer by not using property notation
[iVar retain];
[self.iVar removeFromSuperview];
[self insertSubview:self.iVar atIndex:self.iVar.index];
[iVar release];
Or you could use a temporary variable.

iphone - properties and instance variables

Suppose I have this code...
foo.h
#interface Foo : NSObject {
NSString *aString; // 1
}
#property (nonatomic, retain) NSString *aString;
foo.m
#synthesize aString = _aString;
....
- (void)dealloc {
[aString release];
[super dealloc];
}
My questions are:
do I really need to declare aString in "1"? (see code)
if I am synthesizing aString = _aString, I am already creating an instance
variable, right?
if I am retaining the property on foo.h (#property), why Xcode complains if I release aString in dealloc?
thanks.
You are mixing up the property and the backing variable. "aString" is the property, which you access via method call (e.g. [self aString]). "_aString" is the backing variable, which you access directly (e.g. _aString).
Taking your questions in order:
No. This is an unused variable because you told the compiler to use _aString as the variable. (You don't actually need to declare either one in the modern run-time.)
Yes, as indicated in my answer to the first question.
Because the compiler expects you to send a message to an object, and "aString" is undefined as written. Normally you would use [self aString] to access the object, but this is a special case: in -dealloc and in -initXYZ you don't use accessor methods because of potential side effects. Switch to [_aString release] and everything will work (unless you have ARC, in which case you don't release at all.
With your #synthesize, the instance variable (your "1") should be NSString* _aString.
The reason you use synthesize with a differently named variable is so that you always use self.aString to properly release the old object instead of accidentally overwriting the pointer by directly modifying aString.
Do you have ARC enabled? If so, that's why Xcode complains about releasing it.
To answer your questions in order:
No. There might some sort of "best-practice" reason that I'm missing, but #property will synthesize the instance variable as well.
When you declare aString = _aString, what that allows you to do is directly manipulate _aString without accessing the synthesized getter/setter (by calling _aString) or use the synthesized getter/setters (by calling self.aString).
You are likely releasing it somewhere else, someone else is over-releasing it, or you're using ARC. With NSStrings (and other simple objects that have deep copy method readily available), I find it best to use #property (copy), and _aString = [stringPassedToInit copy], so that you are the only one handling your string's retain count. If you're using ARC, you don't need to worry about retain/release in most instances.
No, you don't need to declare ivars any more (since iOS 3 I think). You can delete the entire { ... } part of your interface declaration and it won't make any difference.
It's complaining because your ivar is named _aString, not aString. You need to say
[_aString release]
instead.
Answers : -
do I really need to declare aString in "1"? (see code) - Now with iOS 4 onwards you won't need to declare.
if I am synthesizing aString = _aString, I am already creating an instance variable, right? - Yes
if I am retaining the property on foo.h (#property), why Xcode complains if I release aString in dealloc? - now you need to use this - self.aString = nil, this will take care.
My answers are:
NO
YES
Try [_string release] instead.

iOS Singletons and Memory Management

I'm certain that I'm missing some fundamental understanding of iOS memory management and, despite lots of reading and searching, I'm still not getting it.
I use a singleton in my app that has info about the user currently signed into it, info accessed from multiple view controllers, etc. It has multiple ivars that are get and set throughout the app. They're declared and propertied in the .h file like so:
NSString *myString;
and are made retained like so:
#property (non atomic, retain) NSString *myString;
and synththesized in the implementation.
I get and set their values in methods in the singleton like this:
myString = #"value";
and
methodLocalString = myString;
In other places I include the singleton -- call it CurrentUser -- I import it:
#import "CurrentUser.h"
Outside of the singleton I get and set it like this:
[CurrentUser sharedCurrentUser].myString = #"Bob";
and
myOutsideString = [CurrentUser sharedCurrentUser].myString;
Most of the time this works great, with the values appropriately persisted from one getting or setting to another. The trouble is that sometimes when I get them that way I find that they've been released (crashing the app), which NSZombieEnabled thankfully tells me.
What I don't get is how his can happen. I thought the singleton was never released, and that therefor retained properties of the singleton would never be released. I'll note that the problem seems to be more common with non-real-object properties like NSDate and definitely-not-object properties like int and BOOL which can't be retained, but it happens with object properties as well.
What am I ignorant about here? And thanks for your patience.
Your problem is:
I get and set their values in methods
in the singleton like this:
myString = #"value";
When you assign directly to the iVar, instead of using the property syntax (self.myString = #"value"), you are bypassing the synthesized setter method, which means that the retain never happens.
Properties aren't magic. They're just a bit of syntactic sugar for the "." access, and the ability to have synthesized getter/setter methods to save you the tedium of writing your own.
self.myString = #"value";
is just shorthand for
[self setMyString:#"value"];
The synthesized setMyString method will do something like:
if (myString != newValue) {
[myString release];
myString = [newValue retain];
}
(assuming retain option on the #synthesize)
Don't use singletons. Your current problem is caused by a simple memory management misconception, but the singleton pattern will only give you more headache in the long run.

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.