I have this in my .h file:
#property (nonatomic,retain) CCTexture2D *tempScreenshot;
Since it says "retain", I'm assuming that whatever value is stored in tempScreenshot is retained.
Do I have to release tempScreenshot in the dealloc method of my class?
Also, if I use the set method to give a new value to tempScreenshot, this new value will be retained, right? What happens to the old value?
Since you're saying "retain" I am assuming this is manual memory management code. If at all possible, you should switch to automatic reference counting (ARC). It dramatically simplifies this work and is faster than the equivalent manual code. Other than support for older OSes, there is almost never a reason to do manual memory management anymore.
Since it says "retain", I'm assuming that whatever value is stored in tempScreenshot is retained.
Whenever you call [self setTempScreenshot:], the accessor will retain the parameter and release the old value. Assigning the ivar directly will not give you any of this. You should always use the accessor except in init and dealloc.
Do I have to release tempScreenshot in the dealloc method of my class?
Yes.
Also, if I use the set method to give a new value to tempScreenshot, this new value will be retained, right? What happens to the old value?
It will be released as long as you use the accessor.
The retain keyword marks the property as retain upon assignment, meaning that on a set, retain will be called on the new value, and release will be called on the old value.
You will need to release the object on dealloc.
In your dealloc method, do: self.tempScreenshot = nil;
This will cause the object to be released. It will then be deallocated assuming nothing else has retained it.
If you were to write your own setter method to retain an object it would look like this.
//Assume an instance variabled name obj for this example
- (void)setAndRetainObjectExample:(NSObject *)newObj {
[obj release];
obj = newObj;
[obj retain];
}
Using the synthesized methods is much cleaner, but looking at it this way may clear up any confusion.
Related
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.
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.
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.
I was trying to track a strage memory allocation bug so I overrode the retain and release methods of my class. I noticed that when assigning an instance of this class to a property of another, the retain count of the object increased, but my redefined retain was never called.
How can this be possible? Are (retain) properties retaining the object without calling retain?
In my machine, the overridden retain was called. (I'm using 10.6.4. I checked this both on GCC 4.2.1 and clang 1.5.)
Could you post your code?
Internally, the synthesized setter for a retain property uses objc_setProperty, the source code of which is available here.
As you see, eventually it calls [newObject retain] when the property uses retain.
Is garbage collection turned on? I don't believe retain is called under GC.
if you don't use self (self.yourproperty), it won't increase the retain count.
I wouldn't be surprised if synthesized properties would modify the retain count without calling retain or release.
I'm having a recurring problem in Objective-C. I'm either releasing things too many time, or not enough. or perhaps I'm not retaining them enough...
Can someone point me at a good reference that will give me a rule of thumb on when I need to retain and release?
For example:
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
if I alloc an object and only need it in that method, do I need to release it? retain it?
Obviously, if I retained something, I needtorelease it, but beyond that, I get a bit lost.
The rules are generally pretty simple. If you get an object in one of the following ways:
id obj = [[MyObject alloc] init];
id obj = [myObject retain];
id obj = [myObject copy];
id obj = [myObject mutableCopy];
then you need to release it at some point -- in the same method, or your dealloc method, generally. In other words, balance your calls to alloc, retain, copy, and mutableCopy with a matching release call.
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
This happens rarely. The documentation for the called method should specify that you are responsible for releasing the returned object; otherwise, you should assume you're receiving an autoreleased object.
if I alloc an object and only need it in that method, do I need to release it? retain it?
Yes, you need to release it (but you don't need to retain it). (You can also use one of the convenience methods that return an autoreleased object if you're only going to use it in that method.)
There is one and only one canonical reference: Apple's Memory Management Guide for Cocoa or iPhone.