Can I send release to an ivar without alloc/init? - objective-c

I have an NSString property:
.h file
#property (nonatomic, retain) NSString *str;
.m file
#synthesize str;
What is the retain count of str without alloc/init? Can I [str release] in a method?

I am assuming your new to the concept of memory management, so I would advise to have a read of the apple docs around memory management before you continue with your development.
Basic Memory Management Rules
You own any object you create.
You can take ownership of an object using retain.
When you no longer need it, you must relinquish ownership of an object you own.
You must not relinquish ownership of an object you don't own.
I will refer you to the Memory Management Policy in the apple docs for a good understanding of memory management
So when you have read the apple docs you will fully understand what is going on in your code, but if you don't this is what is wrong. You can not release an object that you don't have ownership of. This violates point 4 of the Basic memory management rules in the apple docs. To take ownership of this object you must do str = [[NSString alloc] init]; (This is not needed with ARC) in your .m file.
My recommendation though would be to read up about ARC it is a lot better then handling the memory management yourself. As you would no longer have to do things such as [str release]; once you wanted to relinquish ownership of the object as it is done automatically.

You cannot release an object that has not yet been allocated.
Use ARC where possible, and read about changes to Objective-C in the past 2 years: it is no longer necessary to synthesize variables declared in .h in your .m

You shoudn't release an object that has not yet been allocated. But if you do it it means you are sending a message to a nil object. That is safe because a message to nil does nothing and returns nil, Nil, NULL, 0, or 0.0.

Yes you can release this object. Whenever you send alloc, copy, new, retain any of these message to an object. It's retain count increased by 1. And you become the owner of that object. So you must release the object to relinquish the ownership.
And when you use ARC the compiler do it for you. Hope it helps.

As its a retained property you can do self.str=nil; instead of [str release] safely.
You can not do [str release] as we can release only what we alloc and init by ourself and its not init yet.

Related

NSString assignment, release required?

If I have a property in my class like so:\
#interface Test
NSString *str;
#end
And in my init in the .m:
str = #"Test";
Do I need to manually release that in the classes dealloc?
What about this kind?
NSString *myStr = [NSString stringWithFormat:#"%#", someString];
Do I need to release that too?
You should really just use ARC, but to answer your specific question, no: you don't need to release those. You only release what you "own", and you only own things you got from a method that contains one of [new, alloc, retain, copy].
That said, since you don't own those strings, you should retain (or copy) them if you need them to stick around.
You shouldn't have to release if you are using ARC in your project (Automatic Reference Counting). ARC is enabled for iOS 5+ so if you are targeting iOS 5 or higher, you dont have to release anything.
If you're not sure if you're using ARC or not, just try to release/retain. If it shows a warning saying you can't release/retain, ARC is enabled, else is disabled and you'll have to retain & release.
Both constructs1 create autoreleased strings. You need to retain them (explicitly or by assigning to a retained property), otherwise you will end up with dangling references once the autorelease is called2. Once you call a retain on an object, releasing it becomes your responsibility.
A more robust approach with NSStrings is to use copy properties, rather than retaining them. Doing so lets you avoid issues when a NSMutableString passed into your init method gets mutated after you have validated its content.
1 I am assuming that you are asking about pre-ARC version of Objective C tools; otherwise, you will not be able to call retain or release explicitly.
2 This usually happens some time after you exit from the method, and the control passes back to the run loop.

A more definitive answer on when to release an object

I know this has been answered before (sort of) but I've been reading conflicting answers on exactly when or when not to release an object that has not been specifically subclassed via an allocation.
For example, if I do the following:
#property (..., retain) NSMutableArray *myArray;
or in general,
#property (some retain attribute - strong, weak, retain) type myObject;
After synthesization, If I do nothing else to myObject (no allocation or even forget to use it), are there any cases in which I'm still responsible to release it?
There are two totally different answers depending on whether or not you're using ARC. Since the ARC environment is pretty straight forward, I'll just answer from a pre-ARC perspective. The main thing to understand is that all of the talk around property retain semantics is just a distraction from the main point: If you take ownership, you must relinquish it. Relinquishing ownership is done via -release. So, what you need to understand is "What counts as taking ownership?"
By convention, any time you send a message to class that contains any of [new, alloc, retain, copy], you now own that object. The compiler generates setter methods for Objective C Properties depending on the ownership policies you specify. For example...
#property (..., retain) NSMutableArray *myArray;
#synthesize myArray = _myArray;
This generates a method that looks like this1:
- (void)setMyArray:(NSMutableArray *)myArray
{
// This is oversimplified, just to illustrate the important point.
// Again, this is NOT the way a setter would actually be synthesized.
[_myArray release];
_myArray = [myArray retain];
}
So now, when you say something like self.myArray = someArray, you know you've sent a retain message to someArray, and you're responsible for releasing it later. The ideal way to do that is to say self.myArray = nil, because it releases the old value before retaining nil. Note that it's also perfectly safe to send that message, even if you never set anything to the myArray property, because sending messages to nil is okay. That's why it's common to always set owned properties to nil when you're done with them, regardless of how they're being used.
1 For a study on how accessors should actually work, see this article.

Does stringWithFormat create a retain +1 instance?

I'm declaring an ivar of type NSString on a class. To initialize the value of this ivar I use the following code:
NSString *myVar;
-(void)inAnyMethod
{
myVar = [NSString stringWithFormat:#"%#",theValue];
}
Do I have to release this ivar? According to my understanding, it is not my responsibility. But in most cases, strings that I use in this manner cause leaks.
What am I missing?
You do not have to release it, because that is a convenience method that returns an autoreleased object.
The way to know if you are getting something with a retain count of 1 that you will need to release is using the Cocoa naming conventions which say that anything that starts with new, alloc or contains copy in the method name will return a retain 1 object, the others will return autoreleased objects like in this case.
In addition to Oscar Gomez answer, note that when you use class methods (those methods with plus sign that you can find in the documentation and are not included in Oscar Gomez list, e.g. stringWithFormat is one of them), you have not to worry about memory management. If you create your own class method, you should do the same: return an autorelease object.
Regarding your code, it cannot work if you simply assign your ivar to the NSString object (returned from that method). In fact, at some point of your application cycle, the object will be released (it has been put in a pool) and your ivar will not reference any object anymore.
The trick: create a #property with a copy policy or send a copy message like the following:
myVar = [[NSString stringWithFormat:#"%#",theValue] copy];
Copy is normally used when a class has subclasses of mutable type. Otherwise use retain. Once done, you have the possession for that object and you have to remember to release it. If you don't do it you cause a leak.
[myVar release];
P.S. Since Xcode 4.2 there is a new compiler feature called ARC.
Hope it helps.

Confusion on dealloc calls

I have a basic question here.
I know that dealloc will be called when the object's reference count becomes zero,and dealloc releases all the resources hold by the object or frees memory, right?
The object reference count becomes zero if we send release message to that object right?.
Lets consider the following object with its property created as,
#property (retain) NSString* myString;//reference count 1
and dealloc
[myString release];//reference count 0
[super dealloc];
I am not releasing the myString object any where except in dealloc.
My question is who is making myString object reference count to zero so that dealloc will be called?
Please clarify my doubt.
Anything that maintains ownership of the object is responsible for releasing it. For example if the code you posted is the only thing that maintains ownership of the NSString stored in myString then when you call release the reference count will be decreased and the object will likely be deallocated (String literals are different). Now if you passed myString around or something else requested myString and retains it then that code is also responsible for releasing it which may be before or after you release it in the dealloc method.
I recommend referring to the documentation for reinforcing this concept.
Let's say your property myString is within your class MyClass. Each instance of your class is created and (presumably!) released. When that instance is [released], your dealloc method of MyClass is called. Your dealloc in turn calls release on your properties, which in turn invokes their dealloc, and so on until you reach the 'bottom' of this stack of objects using objects.
Your object will only be free'ed if the retain/release pairs match up. If you follow the cocoa memory management (see apple docs - advances memory management programming guide)
rules, you are the only 'owner' at that point - and running dealloc zap's the last reference away - free'ing the object.

How do you tell whether you need to release an object?

Can you describe the naming convention difference between a method that returns an object it has allocated for the caller (and that the caller should release), and a method that returns an autorelease object?
If you declare a property with a retain attribute, do you need to release the property before you set it to nil?
What does the #synthesize directive do?
From apple documentation
You only release or autorelease objects you own.
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.
You use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (to understand when this will be, see “Autorelease Pools”).
Your second two questions are related. All that #synthesize does is to generate additional methods for your implementation file. The arguments to #property (nonatomic, retain) NSString* myString; define the behavior of the generated methods. For example, if you declare a property as retain, the setMyString generated method will retain its argument.
Nonatomic is important because properties, by default, are threadsafe. If you don't need thread safety, you can remove a lot of overhead in your accessor methods.
Finally, the implementation of a retain property is
- (void) setMyString:(NSString*)newString {
[newString retain];
[myString release];
myString = newString;
}
So, saying self.myString = nil effectively releases myString for you. Many people advocate using self.property = nil for retained properties, as opposed to [property release], though I think it just comes down to personal preference.
A good source for memory allocation is listed below by Aaron.
Regarding #synthesize:
Say you have a property P, what you will have to do is write a getter and a setter for it. There are a few common approaches, one of which is that you retain that object when you set that property and release the old value. E.g:
- (void)setP:(PClass *)value
{
[value retain];
[_pInstanceVariable release];
_pInstanceVariable = value;
}
Since this is a very common piece of code, the compiler can automate it for you, if you specify the retain keyword in property declaration and then do the #synthesize in you implementation. The compiler will generate the above mentioned code which means your code will be a lot cleaner without tedious repeating parts.
Same holds true for getters, unless you want something more complex than:
- (PClass *)p
{
return _pInstanceVariable;
}
the #synthesize will do the job
memory allocation information and naming can be found here
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ObjectiveC/Articles/ocAllocInit.html
synthesize is documented here
http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW17
The apple website has excellent documentation, I would recommend searching there first.