Newb Questions from a C# Developer

Discussion in 'Mac Programming' started by Monergist, Dec 22, 2010.

  1. Monergist macrumors newbie

    Joined:
    Dec 22, 2010
    #1
    Hey all,

    I've been playing around with Objective C lately and have 2 questions that reference this code.


    Code:
    #import "Private_TutorAppDelegate.h"
    #import "Card.h"
    #import "CardCollection.h"
    #import "MemoryType.h"
    
    
    @implementation Private_TutorAppDelegate
    
    @synthesize window;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    	// Insert code here to initialize your application 
    	
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	NSMutableString *aBackSide = [[NSMutableString alloc] init];
    	[aBackSide setString:@"1 Back Side"];
    	
    	Card *aCard = [[Card alloc] init];
    	[aCard setFrontSide:@"1 Front Side"];
    	[aCard setBackSide:aBackSide];
    	
    	
    	CardCollection *aCardCollection = [CardCollection new];
    	[aCardCollection addCard: aCard];
    	
    	[aCard release];
    	[aBackSide release];
    	[aCardCollection release];
    	[pool release];
    }
    
    @end
    
    

    AND

    Code:
    
    #import "CardCollection.h"
    
    @implementation CardCollection
    
    //Add card to the collectionOfCards
    //Returns void.
    -(void) addCard:(Card *)inputCard
    {
    	NSString *inputFrontSide = [inputCard getFrontSide];
    	[collectionOfCards setObject:inputCard forKey:inputFrontSide];
    }
    
    Code:
    @interface CardCollection : NSObject {
    	
    	NSMutableDictionary *collectionOfCards;
    	
    }
    
    //Add card to the collectionOfCards
    //Returns void.
    -(void) addCard:(Card *)inputCard;
    
    
    My questions are:

    1. Why do I get compiler warnings about memory leaks in the first code chunk if I only use [pool release] ? All the code samples I've seen seem to make this a catch all for memory management. Is that not the case?

    2. Why does the addCard method not actually add anything to the collectionOfCards? Shouldn't the addCard implementation do just that? When I view the collectionOfCards in the Xcode debugger after performing the add, it says I have 0 elements in the dictionary.

    I would appreciate any help. This code seems pretty straightforward to me, so I'm a bit baffled.
     
  2. lee1210, Dec 22, 2010
    Last edited: Dec 22, 2010

    lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Where did you read to use new rather than alloc/init?

    When does collectionOfCards get an allocated and initialized object pointer assigned to it? If the answer is "never", then you're sending setObject:forKey: to nil.

    The pattern with a pool is to send drain to release any autoreleased objects.

    -Lee

    As a note, autorelease is not a "catch-all". Read the memory management guide for what this actually is for.
     
  3. Monergist thread starter macrumors newbie

    Joined:
    Dec 22, 2010
    #3
    Hey Lee,

    Not sure where I read about the 'new' - but it was just one of about 100 different things I tried to make this work. In previous iterations, I was using alloc/init.

    I did declare collectionOfCards in the CardCollection header. Not sure why I didn't put that in the code snippet. Here it is:

    Code:
    @interface CardCollection : NSObject {
    	
    	NSMutableDictionary *collectionOfCards;	
    
    }
    
    //Add card to the collectionOfCards
    //Returns void.
    -(void) addCard:(Card *)inputCard;
    
    
    @end
    
    
    So, the declaration does not allocate the memory I guess? It simply creates the pointer?

    I will read up on the memory management stuff. I'm used to the garbage collector just doing everything. I appreciate the help!
     
  4. lee1210, Dec 22, 2010
    Last edited: Dec 22, 2010

    lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    The declaration just gets you a variable to hold a pointer. The alloc/init returns a pointer you can store there. The traditional place to alloc/init ivars that are objects would be your init method. Switch back to alloc/init, then implement init (be sure to send init up to super to initialize on up the inheritance tree) and alloc/init your dictionary there. In your applicationDidFinishLaunching: method you declared a number of objects, but couldn't do anything with them until you assigned a pointer to an object that was returned from alloc/init. The same applies to an ivar. It won't be useful until it points to an object.

    Objective-C 2.0 on OS X (rather than iOS) does support garbage collection, but the memory management rules are not too hard and worth learning.

    -Lee
     

Share This Page