1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

static object (memory management)

Discussion in 'Mac Programming' started by sujithkrishnan, Jun 23, 2008.

  1. macrumors 6502

    Hi all,

    I my iPhone app, i am i am having a static object "staticCatalogObj" implemented as follows....
    +(Catalog *)getCatalogObject
    	if(staticCatalogObj == nil)
    		staticCatalogObj = [[Catalog alloc]init];
    		staticCatalogObj.catalogDictionary = [[NSMutableDictionary alloc] init];
    		staticCatalogObj.itemsArray = [[NSMutableArray alloc]init];
    	return staticCatalogObj;
    I am calling this method in many view controllers to get the same object.
    What all things i want to implement / and the necessary releasing statements i want to add to this part??

    In many view controllers i have, i am getting this object by

    Catalog localInstanceOfCatalog = [Catalog getCatalogInstance];
    // modify the catalog localObject as per requirement...
    [localInstanceOfCatalog release];
    Is this enough from memory point of view???
  2. macrumors 6502

    If you expect client code to release your object after they're done with it, shouldn't you add an extra retain each time you hand it out..?
  3. macrumors 65816


    The first part is the correct way to implement a singleton. You may also want to add the following to make sure that the more than one instance of the class cannot be created (if its only your own code, this doesn't matter as much, but its good practice for libraries and such).

    +(id)alloc {
    	NSAssert(sharedCatalogObj==nil,@"Attempted to allocate a second instance of a singleton.");
    	return [super alloc];
    In the second part, you're releasing an object that was never in your ownership. In other words, you're releasing it without retaining it first. You should remove that last release line as long as all that code is occurring within the same method.

    If this catalog object is the same as the gigantic object your were talking about in the other thread, then you should consider other ways of accessing the data that won't result in you getting memory warnings all the time because of a single big object taking up all the available memory space.


    Wrong solution to the problem. The "client code" (which I'm guessing is a reference to the 2nd block there) is incorrect in that it releases an object it never took ownership of. Taking ownership of an object that's not going to be released by the same code, as you suggest he do in the sharedObject method, just compounds the problem. You may get technically correct behavior, but that's bad coding practice to retain in one part of the code simply because a release is expected in a completely separate part. That would be completely unmaintainable.
  4. macrumors 6502

    i am wondering why apple put memory management burden over the developer for iPhone rather having garbage collector for it....

    My doubt is that i am having many localCatalogInstances in mnay of my classes, like

    localCatalogForFistScreen = [Catalog getCatalogInstance];
    localCatalogForSecondScreen = [Catalog getCatalogInstance];
    Is all these add to increase in retainCount of the singleton object?
    I thought in that way and thats why i  made that release statement there in client who calls the method...
  5. macrumors 6502

    Yeah SB...

    This is the object that i mentioned which want to keep it in memory for generating my all views.... All the relation between menus->categories->sub categories are represented in this object...

    Eventhough i go for archiving (which i did) i want to load (unarchive) the catalogObject to generate my menus (tableViewControllers)...
  6. macrumors 68040

    Garbage collection requires more computation, which equals lower battery life. It can also result in less efficient memory usage (assuming the developer does proper memory management), which is bad for a device with limited memory.
  7. macrumors 65816


    That local variable assignment alone isn't increasing the retain count of the singleton object, no.
  8. macrumors 603


    As suggested elsewhere, perhaps the best place to allocate the Catalog object is in the alloc or init methods.

    If you do it as you've done above, I'd suggest autoreleasing the Catalog object as you return it; or consistency reasons. The calling code than then retain it, as needed.
  9. macrumors 65816


    Err, autoreleasing the singleton object in the sharedObject method? That wouldn't make any sense. The object is created with a retain count of 1 because of the alloc-init on the first call of sharedObject, and in the dealloc method the sharedObject should be released. That means that the singleton class has fulfilled its memory management obligation - it takes ownership of the object at creation, and releases ownership of the object on dealloc.

    Here's my idea for solving your overarching problem:

    You want to release the singleton object at some point to in the execution to save memory, so create a method like this that you can call in your didReceiveMemoryWarning: methods.

    +(void)destroySingleton {
    	if (sharedObj) {
    		[self saveSingletonDataToDisk]; // Some method to save all that data to disk
    		[sharedObj release];
    		sharedObj = nil;
    Of course, you'd want to add something to your init to load the saved data again from disk. This would mean that the singleton data could be released when not needed (say, on a memory warning sent to a view controller) and created again when needed.

    The correct way to use the singleton object in the rest of the code, then, would not be to retain a reference to it in your other classes but to access [MyObjectClass sharedObject] whenever you wanted to use it for some reason. That way if the singleton object was currently residing in memory, it would simply return the pointer to it, and if it didn't exist yet or had been released because of a memory warning it would be loaded from disk again, created, and returned.

    The key part here, of course, is to not retain references to the singleton in other parts of your code so that when you call [MyObjectClass destroySingleton] it is, in fact, released and not leaked. That would be bad, and would pretty much result in worse memory performance than before. Of course, you should try to minimize how often you access the shared object since caching and loading it all the time is also bad. I'm not sure exactly what you're storing in there, but try to use it as little as possible or you're not going to realize any benefits with this.

    If you need to access it constantly, then you'll probably want to ignore everything I said and find some other solution. To be honest, though, I can't see why you need to keep so much data in memory constantly such that you're getting memory warnings all the time. What exactly are you storing in there that's taking up so much memory, anyway?

    This would seem, to me at least, to be the best way to handle your memory problem sujithkrisnan.
  10. macrumors 6502


    Thanks alot for the detailed explntn...

    I am creating a shopping application, which comprising 20 shops, having around 900 items as product...
    All these are gettign n=by parsing an xml at a URL...
    I want to keep this all shop -product structure to generate the navigation menu for user to navigate..

    I am trying to minimize the server-hitting, so i am downlaoding all the shop-products to device...

    Okie, i will try some other design....
    Thanks again..

Share This Page