Will releasing an array also release its elements? - objective-c

I alloc my NSMutableArray, and add objects that were alloced as well. Will calling release on my array also release the elements within, or do I have to release each element manually first?

Objects in obj-c collection are released when that collection is deallocated (that's not the same as being released). So in practice if you add your object in collection, collection manages its objects ownership and you don't need to put extra releases for its elements.

Check the Collections Programming Topics guide. More specifically, the
Arrays section and the Array Fundamentals topic:
When an array is deallocated in a managed memory environment, each
element is sent a release message.
So if releasing an array brings its retain count to 0, and it is then about
to be deallocated, at this point the objects will receive a release message.
Otherwise, releasing an array just decrements its retain count as any other
regular object.
Also, when you place objects in the array, they receive a retain message, as
the guide explains.

Related

Potential Leak of Object stored into a NSMutable dictionary (GPUImageFramework) iOS 8+

I am new to Objective C, and I would really appreciate any help resolving a memory leak. I am trying to resolve memory management issues that occur in the GPUImageFramework.
In the method below I am getting the following messages highlighted in blue:
Method returns an Objective-C object with a +1 retain count
Object leaked: allocated object is not referenced later in this execution path and has a retain count of+1
-(void)setAndExecuteUniformStateCallbackAtIndex:(GLint)uniform forProgram:(GLProgram *)shaderProgram toBlock:(dispatch_block_t)uniformStateBlock;
{
[uniformStateRestorationBlocks setObject:[uniformStateBlock copy] forKey:[NSNumber numberWithInt:uniform]];
uniformStateBlock();
}
enter image description here
I take it that the method being stored in the NSMutable dictionary needs to be released into memory.
Please can somebody point me in the right direction?
I have ARC enabled within the GPUImageFramework
You either need to enable it for your project, not just for the framework, or you need to handle memory management manually.
The sub-expression [uniformStateBlock copy] returns an object with, in the language of the error, "+1 retain count"; i.e. an object the caller "owns" and which the caller must release.
When your code inserts an object into the array the array itself also takes ownership, i.e. does a retain. It does not take ownership from the caller, it is still left owning the block returned by copy and it is this ownership which is never relinquished which results in the leak, as the error states.
If you enable ARC it will take care of this and release the callers ownership of the block at the appropriate point.
Otherwise you can leave ARC off and insert a release call when the caller no longer requires the block (which still leaves the array with ownership).
HTH

What happens to the memory of an object when it is created inside a method in Obj-C?

When you instantiate an object inside a method, when that method is called the object will be allocated memory but what object will hold reference to this object or will it be automatically be deallocated when the method ends. Thanks.
In OS X and iOS 5+, Objective-C uses Automatic Reference Counting. In this case, the object is freed when it goes out of scope, just like you'd expect.
Before that, you needed to explicitly retain and release objects. Here's a useful article from 2010 on this topic.
Objective-C in retain count mode (not using garbage collection) is a
simple idea. When you explicitly allocate an object it gets a retain
count of 1 and when you call release or autorelease on an object it's
retain count gets decremented and then the object will be collected.
It is the only mode available on iOS Devices and has been in use on
Mac OS X since the beginning of the OS.
Short answer, if you are using ARC (Automatic Retain Count) or if the object is autorelease it will be sent a release message when appropriate.
If you are manually managing the memory, you have to manually send a release method to those object whenever they are returned by either new, alloc, retain, copy or mutableCopy, otherwise the object will leak as you will be losing any reference to it when the stack gets teared down.
If your application is ARC then it will be dealloc'd after it goes out of scope. If the object is a property of a class then it will be cleaned up by different rules depending on whether it is defined as strong or weak. Strong means that the object will not be cleaned up as long as the object that owns it points to it (so as long as the object that owns it exists then it will not be cleaned up). Weak means that the object will not be cleaned up as long as another object points to it.

Retain count and dealloc in iPhone

I want to ask about the iPhone application and objective C question. In the implementation program, there are function called 'dealloc', does this function only be called one time by the application?
For example, if I alloc a object and retain it 2 times, the retains count is 2 and I never use 'release' in the program, unless in the dealloc. Will the object be removed from the memory, or the objective will be removed from the memory. Thank you.
In the implementation program, there are function called 'dealloc', does this function only be called one time by the application?
Yes. -dealloc destroys the object. Trying to send any message to it again, including -dealloc is an error.
if I alloc a object and retain it 2 times, the retains count is 2
Careful. The retain count is at least 3. Other things than your code might retain the object. It's better not to worry to much about retain counts and only think in terms of ownership.
Each alloc, new, copy or retain is an claim of ownership. The object's dealloc method will only be called when all claims of ownership have been relinquished. A claim of ownership is relinquished by sending -release. So if you never release an object except in its own dealloc, you'll never release it.
dealloc is called once by the system when the object is destroyed (when its reference count reaches 0). If you have member variables in your class that you alloc in your init function, you must release them in your dealloc function.
If you give someone a pointer to one of those member objects and they retain it, the member could survive the release in your dealloc, but by sending a retain message they are taking responsibility for sending a release message later, ensuring its eventual destruction.

Do removeAllObjects and release of an NSMutableArray both have the same functionality?

I have written the following line of code:
NSMutableArray *array=[[NSMutableArray alloc]init];
This allocates some memory. My question is, how can we later release this memory, whether using removeAllObjects method or [array release]?
Do both methods have the same functionality?
When you add an object to the array, the object's retain count will increase by 1. When you remove that object from the array, retain count will decrease by 1 to balance it out. But if you release the array, all objects will automatically receive a release message. So you don't need to call removeAllObjects before releasing the array.
Technically, these two method are not same. If you call removeAllObjects, the array will become empty and all objects will receive a release message but the array itself is still not released. The array will be released when you call release on it.

Does NSArray copy objects?

When I make an NSArray using +[NSArray arrayWithObjects:], does it copy those objects? If I release the objects after adding them to the array, will I run into problems?
No, it doesn't copy them. It retains them. Yes, you can safely release the objects after adding them to the array.
The docs, as always, spell this out very clearly:
Arrays maintain strong references to their contents—in a managed memory environment, each object receives a retain message before its id is added to the array and a release message when it is removed from the array or when the array is deallocated. If you want a collection with different object ownership semantics, consider using CFArray Reference, NSPointerArray, or NSHashTable instead.