Sunday, May 1, 2011

Fundamental Objective-C question...driving me crazy

Its been a long time since I've done any programming. Used to be 'ok' at reading C & C++...never wrote much.

I have an extremely simple Class that I want to use to manipulate the contents of an Array (using NSMutableArray). The Array needs to persist as an Object so I can make multiple updates to it during a single run of my program (not worried about storing state data to disk yet)

Here is my problem. I am not clear on where/when I should Alloc/Init my Array object so that it will be in a usable state each time a button is clicked on my iPhone's View.

I am trying to create a SubClass of ViewController that includes an Array as an instance variable, which can then be referenced in the code that responds to button clicks from the View. I've tried 3 approaches

  1. I've tried to just reference the array instance variable in a method I've written as part of the same class. No Alloc/Init anywhere in this version of code. When I call the addObject function it appears to fail because the array object has not been allocated/initialized.

  2. I've also tried to Alloc/Init an instance of my array object in the viewWillDisplay method. The Xcode compiler complains that my newly allocated object is never used.

  3. For kicks, I've done an alloc/init within the scope of the 'button click' method i'm writing...but of course that allocates a new instance each time I click my button.

Here is what I've got in the .h and .m files for my example (this shows scenario 1)

Would really appreciate it if someone could fill in the GIANT blank I've obviously got in my understanding of how Instance Variable objects are supposed to be used. (I've read a wide variety of Apples docs on Obj-C..etc. Also googled my brains out trying to find an explanation.

The .h:

#import <UIKit/UIKit.h>

@interface ArrayManagerViewController : UIViewController {
    NSMutableArray *buttonArray;
}
- (IBAction)buttonClicked:(id)sender;

@end

And the .m

#import "ArrayManagerViewController.h"

@implementation ArrayManagerViewController

- (IBAction) buttonClicked:(id)sender {
    NSString *senderTitle = [sender currentTitle];
    int intSenderTitle = [senderTitle intValue];
    [buttonArray insertObject:[NSString stringWithFormat:@"%d",
                                                         intSenderTitle]
                      atIndex:intSenderTitle];

    for (id obj in buttonArray)
        NSLog(@"Object Value %@", obj);
}
From stackoverflow
  • Okay, Objective C can be a little annoying because you have basically two kinds of syntax, C and Smalltalk. You need to create your array with code something like

    buttonArray = [[NSMutableArray alloc] init] ;
    

    There's a nice lightweight tutorial here.

  • If your array is used throughout the lifetime of your ViewController, you can probably alloc/init the array in the ArrayManagerViewController init (override) method, and call release in a dealloc override.

    @implementation ArrayManagerViewController
    
    - (ArrayManagerViewController *) init
    {
        if (self = [super init])
        {
            [[buttonArray alloc] init];
        }
    
        // handle errors...
    
        return self;
    }
    
    - (void)dealloc
    {
        [buttonArray release];
        [super dealloc];
    }
    
    // other methods
    
    @end
    
    Andy White : I think the hellra1ser is more correct, a ViewController usually has a more specific version of "init" than what I have above. I just wanted to give a general idea of how to do this.
  • You should know that you must initialize you instance variable in constructor

    message that initialize UIViewController is (usually)

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    

    so your implementation will be

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
           // Custom initialization
           buttonArray = [[NSMutableArray alloc] init];
        }
        return self;
    }
    

    and don't forget to release your buttonsArray in dealloc message

    - (void) dealloc {
        [buttonsArray release];
        [super dealloc];
    }
    

    P.S.:just read ObjC basics and Cocoa Memory Management on developer.apple.com before starting writing the code

    Andy White : Your answer is right, there is a more specific version of init than what I have.

0 comments:

Post a Comment