calling -retain multiple times on the same object - iphone

What happens when you call -retain on an object many times? Is it OK to just release it once at when you're done using it?

consider the name "reference counting".
you must match each retain with a release (or autorelease).
when reference counting, your program may hold one or more references to an object. you add a reference by retaining the object. when you are done with the object, you forfeit the reference using release or autorelease. when all references are returned, the retain count reaches zero and the object is destroyed.
object lifetimes are also affected by autorelease pools; a convenience mechanism which reduces the number of manual retains/releases as well as reference counting complexity (in some cases). you should read up on autorelease and autorelease pools for a further understanding of this mechanism.

Always remember this three things.
1.) Whenever you pass a retain message to any object, its retain count increases by 1.
2.) And subsequently when you pass a release message to any object, its retain count decreases by 1.
3.) And whenever you are done with the object, always check that its retain count is 0.
Hence, the number of times you retain an object should always be equal to the number of times you release that object.
You can check apple documentation regarding memory management here.

How many times you call this method(retain) that many times Memory is allocated To that Object .you can Get Through Retain Count How many times Object Is being Allocated.
Its creates memory Issues.
If the Object Retain Count Is zero Then That Particular Object IS Not Unavailable to be used for other.
that to If your Retain 10times One Object if U release Once its not being released.
retain Increased by 1 count And Release Decreased by 1. if object having retain count 0 that object is unavailable.

Related

how objects values are retained when we drain the pool at the end of run loop

I know this sounds like a dumb question but I need to ask this. Well I read that autorelease pool is drained after one iteration of run loop after it has handled events. My question is that then how come my apps objects are retained after I clicked on button. So, by definition It should destroy all the objects which I have created (may be I have assigned some values to objects) after I click on button. But that doesnt happen ? right ? I can click my button again and again but I dont lose any object data.
Correct me if I am wrong somewhere.
You should watch a video or two from https://developer.apple.com/videos/ - Great introductions to memory management and such. And I also strongly recommend you look into ARC as soon as you grasp the basics of retain/release/autorelease.
All that the autorelease pool does is decrement the retain count of objects in the pool when it is drained. If that results in the retain count becoming zero, the object will be destroyed (dealloc'ed).
However, if an object has been retained more than once, the retain count will be greater than zero so it will not be destroyed (note that objects are created with a retain count of 1.)

Don't worry about `retainCount`? Really?

I've been told to not worry about retain counts. I understand that I shouldn't decide to release or retain using conditional logic based on retainCount, but should I not worry about it? I thought these correspond to memory usage in some way.
For instance, if I have a bunch of subviews of UIView that I've also put into an NSArray to be able to iterate through them, doesn't that double the retain count and therefore the memory use of the application? If so, is this costly or trivial, if the subviews are, say, 500 UIControl instances? This is assuming that I need the 500 instances, of course.
The value returned by retainCount is the absolute number of times the object has been retained. A UIView comes from a framework whose implementation is opaque. The implementation details aren't something you should worry about save for the documented interface you interact with.
And within that implementation, instances of UIView may be retained any number of times as a part of the implementation. In terms of memory, the actual number of retains is meaningless; 1 is the same as 5.
The only thing you should ever be concerned with is how your code changes an objects retain count.
If your code increases the retain count, it must decrease it somewhere or the object will stick around forever. If you retain, you must release (or autorelease). If you copy, you must release or autorelease. If you new or alloc, you must release (or autorelease).
That is it.
You're not supposed to be worrying about retainCount because it's often a misleading implementation detail of the reference counting system. What you're supposed to concern yourself with is following proper object ownership policy.
I post this once in a while from Apple's documentation:
Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.
As for your last question, your memory usage is not going to double from adding objects from one array to another array. The retain count is just an unsigned integer in the object that gets incremented by 1 when something claims ownership of it. But again, don't concern yourself with that.
For instance, if I have a bunch of subviews of UIView that I've also put into an NSArray to be able to iterate through them, doesn't that double the retain count...
Yes, it will.
... and therefore the memory use of the application?
No! The conclusion is wrong. 1000000 takes as much space as 0 when stored as a 32-bit integer.
The reason they say not to worry is that the retainCount field can often be very misleading. Aside from not knowing when the autorelease pool was last flushed or how many times an object has been autoreleased since, there are also some complicated internals, and system components could be temporarily holding references in ways that cannot be predicted. So if you start to study the retainCount you'll likely spend a lot time trying to figure out what other parts of the system are doing with various objects, which is not likely to help you get your application right.
You should design how your application works so that memory usage is not excessive.
You should worry about how many objects you have in memory, and how many times you have retained them (this is a number that will be less than the retainCount), and making sure you release them as many times as you retain them.
Calling retain on an object multiple times still only results in a single copy of the object being in memory.
To check for memory usage and/or leaks, you use the instruments leaks detector.
The retain count is just a number. An object whose retain count hits zero will get deallocated; aside from that, it doesn't matter if it's been retained once or fifty times.

Using an object beyond Autorelease context

under the "Guaranteeing the Foundation Ownership Policy" in Apple developer's site article on Autorelease pool
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-997594, they talk about extending an object's lifetime beyond the Autorelease pool.
Can someone give me a situation where this concept could be used?
Short answer: What the documentation is saying is that if you need to keep an object that has been autoreleased in an autorelease pool, you need to retain it.
Long answer: For instance, say I need to do a certain operation to 1000 objects. Once I'm done with these objects I'm going to autorelease them. Without an autorelease pool, they're going to be eventually released, but holding those 1000 objects in memory can make your program really slow (at least until they're autoreleased).
In order to solve this issue, I'm creating an autorelease pool that will be cleaned every 100 objects. However, what happens if I need to keep the last object of the last batch around? I still need to purge those other 99 objects. What I'm going to do is send a retain message to that very last object then clean the autorelease pool.
This way the autorelease pool will notify the system that it no longer wants those 100 items, but you've already let the system know that you do need one of them. If the object had a previous retain count of 1, then it'll still be around:
1 (original retain count) +1 (your retain) -1 (autorelease pool release) = 1.
This preserves the object after the autorelease pool is done with it.

Is this a memory management problem when using multiple threads?

Example: In my main thread (the thread that's just there without doing anything special) I call a selector to be performed in a background thread. So there's a new thread, right? And now, inside this background thread I create a new object which holds image data. Next I use that object and want to keep it around for a while. How would I store a reference to that object so I can release it later? Or will the thread be alive as long as this object exists? How does a thread relate to objects which were created in it?
Maybe someone can explain this in clear words :-)
Storage location and thread creation are two separate concepts. It doesn't matter which thread created an object in terms of who will finally 'own' it or when it will be released later.
Unfortunately, there's no clear-cut answer to your question, but I'd start by thinking about whether this object is a singleton, or whether it's a cache item that can be purged, or whether it's a result object that you need to pass back to some other selector asynchronously.
If it's a singleton, put it in a static var, and never release it (or, consider doing so in response to a low memory warning)
If it's a cache, then have the cache own the item when it's inserted, so you don't have to worry about it. You might need an autorelease to do this, but be careful when using autorelease and threads since each thread may have its own autorelease pool which gets drained at different times.
If it's an object that you need to pass back to another caller, you want to autorelease it as you return and let the caller pick up the ownership of the item.

Does a collection send a -release message to all objects it holds, if I send it an -release?

I've been reading that if an collection "gets released" it releases all it's objects as well. On the other hand, I was also reading that a collection would release it's objects as soon as the collection gets deallocated.
But the last thing may not always happen, as apple says. The system decides if it's good to deallocate or not. In most cases it will, but in some cases not.
So I am wondering if a collection can cause memory leaks like this?
And when it does -release all it's objects upon an -release message to the collection itself, then it should actually -retain all objects inside the collection as soon as I -retain the collection itself.
Help me to get a clear picture about that. Thanks!
When you add an object to a collection, it's retained by the collection until it's removed or the collection is deallocated. Subsequent retain or release messages sent to the collection don't change the retain count of objects inside the collection.
In other words, think of it in terms of ownership, rather than counting retains.
Sending an object a release drops its retention count. When its retention count hits zero, it's destroyed. When a container is destroyed (not released), it's objects are released (but if their retention count is non-zero for other reasons, not destroyed).
Short answer: This will all work the way you're expecting, your problem is that you're viewing "released" as meaning "destroyed." They're different.