Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a good way to release memory?

I have been programming on iPhone for quite sometime and have had bad experiences with memory management. I was wondering if the following way is a good way to release memory.

int count = [someObject retainCount];

for (int i = 0; i < count; i ++) 
{
[someObject release];
}

This method was an act of desperation in a few situations (particularly UIWebViews) I had faced. The variable's retainCount is reduced to zero which will release the memory being used by it. The method is a little dirty but are there any bottlenecks associated with it?

like image 600
HG's Avatar asked Jun 30 '11 12:06

HG's


4 Answers

You should not rely on the retainCount because there are possibility of retaining the object by iOS frameworks,

Read below what Apple say about retainCount.

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.

To understand the fundamental rules of memory management that you must abide by, read “Memory Management Rules”. To diagnose memory management problems, use a suitable tool:

like image 150
Jhaliya - Praveen Sharma Avatar answered Nov 08 '22 21:11

Jhaliya - Praveen Sharma


This code is an absolute no-go. It just hides your programming mistakes - and it does so in a very bad manner.

Please learn proper memory management. There is no substitute.

Here is the memory management programming guide. It is worth reading more than once.

like image 40
Eiko Avatar answered Nov 08 '22 19:11

Eiko


As others have mentioned, -retainCount is virtually useless. When you're new to the memory management/reference counting in Objective-C, it can sometimes be tempting to try to use -retainCount to help understand how reference counting works, but in reality, it can be (seemingly) confusing at best.

The code you posted is potentially dangerous, in and of itself, depending on your surrounding context of how someObject is being used. It can also be dangerous when applied to other situations you weren't expecting. Take constant NSStrings created using the @"a string" compiler directive: these strings are created and are designed to never be released. So applying your code like in the following example would result in an infinite loop:

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *string = @"theString";

    NSLog(@"retainCount == %lu", (unsigned long)[string retainCount]);

    for (NSUInteger i = 0; i < [string retainCount]; i++) {
        [string release];
    }

    [pool drain];
    return 0;
}

This prints:

2011-06-30 08:40:16.287 retainCount[35505:a0f] retainCount == 1152921504606846975

and then goes into an infinite loop.

like image 7
NSGod Avatar answered Nov 08 '22 21:11

NSGod


I cannot say NO emphatically enough!

Take this example of your code in action :

// Create an autoreleased object
MyObject *myObject = [[[MyObject alloc] init] autorelease];

// Run your code to make it dealloc itself
int count = [myObject retainCount];
for (int i = 0; i < count; i ++)
    [myObject release];

Your code would force myObject to be dealloced.

However, myObject has been put into the autorelease pool as well - as soon as the pool started to release it's objects your app would crash because myObject doesn't exist anymore!

The rule is simple : Call release each time you use init, new or copy. Otherwise it's not your problem.

like image 6
deanWombourne Avatar answered Nov 08 '22 21:11

deanWombourne