Memory Leakage.

Discussion in 'iOS Development' started by SkylarEC, Aug 27, 2008.

  1. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    Sadly, I think I need to educate a few of you on what a memory leak is. Simply put, it is a when you allocate memory, then release all pointers to that segment of memory. The memory location is still allocated, and is now unusable.

    When you close an application (on ANY modern OS, ie, Vista, Mac OS X, and even iPhoneOS 2.0) the memory allocated my the application is automatically deallocated by the OS. Meaning that any memory leaked while the application was running is no longer unobtainable and goes back into the memory pool for other applications to use it.

    What happens if you don't include dealloc methods? In the majority of the applications I've seen on the iPhone, nothing. Nothing is leaked. Most of you create applications with no need to release your objects until the application closes. The memory that object uses is deallocated automatically by the OS. Neat huh?

    Why even bother using dealloc methods then? Well, what if you ever need to reuse your code? Let's say that an youObject in YourSimpleApp closes without needing to release that object. You now make YouMoreAdvancedApplication and use that same object. In YourMoreAdvancedApplication, you need to create several of instances of yourObject. Let's say that you put it into an array of 100, or something. You do something with that array, then release it. Good, except for the fact that you just destroyed all references to all the memory that is allocated by those 100 objects. You have now leaked all the memory locations those objects were occupying. And what happens when you recreate and release another array of 100 objects? You leak yet some more.

    Not to worry, that memory will be deallocated when you close the application. Just know that while your application is open performance will go steadily downhill. It may even reach the point where you have used up all the memory the system has available. Uh-oh. Looks like your app is in for a world of trouble...

    But, when will I ever need an array of 100 objects? All the time. What if you make a game and have 100 spaceships to shoot? What if you are accessing the contents of a textfile, and want each line to create a spot in you array? What if you are making a file manager with the need to recreate your tables? You'd better be deallocing, else you're leaking, baby.

    Okay, well as long as I include dealloc methods, I won't have memory leaks, right? Wrong. There are other possible ways to create memory leaks. Ignoring RAII for a minute, you can create a memory leak by simply not freeing a variable you used. For example:
    Getting the brightness preferences:
    Code:
    - (void)getBacklightLevel;{
    	NSNumber *bl = (NSNumber*) CFPreferencesCopyAppValue(CFSTR("SBBacklightLevel" ), CFSTR("com.apple.springboard"));
    	previousBacklightLevel = [bl floatValue]; //previousBacklightLevel is a float declared in the main function.	
    }
    What's wrong with that? I created a function, created a local variable that exists within the function. As soon as I leave the function, the variable should be destroyed and the memory freed.

    Well, theoretically, yes. But remember that I told you to ignore RAII. Certain languages, like C, don't adhere to RAII. Meaning that you'll need to free your own variables. Else. the reference to the allocated memory spot is lost. The next time that function is called, it will allocate a separate section of memory for its variable.

    Core foundation is a C framework. Meaning, among other things, that its variables must be released.

    Here's a correct solution:
    Code:
    - (void)getBacklightLevel;{
    	NSNumber *bl = (NSNumber*) CFPreferencesCopyAppValue(CFSTR("SBBacklightLevel" ), CFSTR("com.apple.springboard"));
    	previousBacklightLevel = [bl floatValue];	
    	CFRelease(bl);
    }
    Now, using CoreFoundation as a reference might just be abstracting the issue just a bit, so I'll repeat the same free example with code you probably already use.

    Bad:
    Code:
    - (void)openTheFile{
    	char buffer[262144], buf[1024];
        	
    	file = fopen("/Applications/YourMoreAdvancedApp.app/files/someFile.html", "r");
    	buffer[0] = 0;
    	while((fgets(buf, sizeof(buf), file))!=NULL) {
    		strlcat(buffer, buf, sizeof(buffer));
    	}
    }
    
    Good, notice how we close the file when we are done with it:
    Code:
    - (void)openTheFile{
    	char buffer[262144], buf[1024];
        	
    	file = fopen("/Applications/YourMoreAdvancedApp.app/files/someFile.html", "r");
    		buffer[0] = 0;
    	while((fgets(buf, sizeof(buf), file))!=NULL) {
    		strlcat(buffer, buf, sizeof(buffer));
    	}
    	fclose(file);
    }
    One more time, yet even more simplified, Bad:
    Code:
    - (void)createAStringAndSetItAsALabel{
    	
    	char *yourString;
    	
    	//Do whatever you need set a string to your array.
    
    	*yourString = tolower(*yourString);
    
    	yourObject.itsLabel.text = [NSString stringWithUTF8String:yourString];
    
    }
    Good:
    Code:
    - (void)createAStringAndSetItAsALabel{
    	
    	char *yourString;
    	
    	//Do whatever you need set a string to your array.
    
    	*yourString = tolower(*yourString);
    
    	yourObject.itsLabel.text = [NSString stringWithUTF8String:yourString];
    
    	free(yourString);
    }

    Well, I'm okay, I autorelease all my objects, right? Actually, Apple admits that autorelease is broken and advises coders against using it. There are a few things that it works wonders for, but the majority of the time, it does nothing. Don't rely on it to manage your memory for you.


    And with that, happy coding.
  2. Nt1440

    Nt1440 New Member

    Joined:
    Nov 9, 2007
    Messages:
    1,431
    Likes Received:
    26
    stupid question time!!

    is that java? it looks very similar to what im (beginning) doing in my computer science class
  3. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    Everything I posted is Objective-C or C.
  4. gojohnnyboi

    gojohnnyboi Well-Known Member

    Joined:
    Jan 25, 2008
    Messages:
    3,339
    Likes Received:
    55
    this is good. well needed for some peoplez
  5. Cyanidepoison

    Cyanidepoison Active Member

    Joined:
    Jan 18, 2008
    Messages:
    1,076
    Likes Received:
    2
    Garbage collection takes care of that for you in Java and just about any other new language.
  6. mitch88ell

    mitch88ell New Member

    Joined:
    Jan 20, 2008
    Messages:
    492
    Likes Received:
    0
    Device:
    iPod touch
    Wow, great informative information. Well recommended for people to start coding apps.
  7. Totally 1337

    Totally 1337 Active Member

    Joined:
    Mar 27, 2008
    Messages:
    3,966
    Likes Received:
    17
    Device:
    iPhone 4S (Black)
    FINALLY!!!! I have always wondered what this means!!!! Thanks!!!!!!!111!!!!one!!!2!!!!!!@!!!!
  8. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    I feel I need to append this a little bit. In one example I gave, I made a glaring mistake:

    Code:
    - (void)getBacklightLevel;{
    	NSNumber *bl = (NSNumber*) CFPreferencesCopyAppValue(CFSTR("SBBacklightLevel" ), CFSTR("com.apple.springboard"));
    	previousBacklightLevel = [bl floatValue];	
    	CFRelease(bl);
    }
    I cast the CFFLoat to an NSNumber. Attempting to call CFRelease() on it will cause the app crash (I presume). Enable your NSZombies to find out for sure.



    Also, objects that are created with a convenience constructor do not need to be manually released. Nor should you call autorelease on them.
    Code:
    //GOOD
    [[[NSString alloc] initWithString:@"ReleaseMe"] autorelease];
    
    //BAD
    [[NSString stringWithString:@"ReleaseMe"] autorelease];
    
    [/CODE]
  9. ipodgreatmaster

    ipodgreatmaster Member

    Joined:
    Feb 20, 2008
    Messages:
    186
    Likes Received:
    0
    Device:
    4G iPod touch
  10. NolesFans

    NolesFans New Member

    Joined:
    Sep 23, 2008
    Messages:
    404
    Likes Received:
    0
    Device:
    iPod touch
    So "autorelease" is broken? sadly for coders use it.

Share This Page