bkbeachlabs
bkbeachlabs

Reputation: 2171

creating a Mutable array that can be added to in later clicks of the same button?

General noob questions:

(1) How can I create an NSMutable array in a buttonClicked action that I can add more entries to during subsequent clicks of the same button? I always seem to start over with a new array at every click (the array prints with only 1 entry which is the most recent button's tag in an NSLog statement).

I have about 100 buttons (one for each character in my string called "list") generated by a for-loop earlier in my code, and each has been assigned a tag. They are in a scrollview within the view of my ViewController.

I wish to keep track of how many (and which ones) of the buttons have been clicked with the option of removing those entries if they are clicked a second time.

This is what I have so far:

-(void) buttonClicked:(UIButton *)sender
      NSMutableArray * theseButtonsHaveBeenClicked = [[NSMutableArray alloc] initWithCapacity: list.length];
      NSNumber *sendNum = [NSNumber numberWithInt:sender.tag];
      [theseButtonsHaveBeenClicked addObject:sendNum at index:sender.tag];
      NSLog(@"%@",theseButtonsHaveBeenClicked);
}

(2) I have read that I may be able to use a plist dictionary but I don't really understand how I would accomplish that in code since I cant type out the items in the dictionary manually (since I don't know which buttons the user will click). Would this be easier if I somehow loaded and replaced the dictionary in a plist file? And how would I do that?

(3) I also have no idea how I should memory manage this since I need to keep updating the array. autorelease?

Thanks for any help you can provide!

Upvotes: 4

Views: 236

Answers (1)

pchap10k
pchap10k

Reputation: 2086

Okay, firstly you are creating a locally scoped array that is being re-initialised on every call to buttonClicked:. The variable should be part of the class init cycle.

You will also be better off with an NSMutableDictionary instead of an NSMutableArray. With a dictionary we don't have to specify capacity and we can use the button's tags as dictionary keys.

Here's what you need to do, these three steps always go together: property/synthesize/release. A good one to remember.

  //Add property declaration to .h file
  @property (nonatomic, retain) NSMutableDictionary * theseButtonsHaveBeenClicked;

  //Add the synthesize directive to the top of .m file
  @synthesize theseButtonsHaveBeenClicked;

  // Add release call to the dealloc method at the bottom of .m file
  - (void) dealloc {
    self.theseButtonsHaveBeenClicked = nil; // syntactically equiv to [theseButtonsHaveBeenClicked release] but also nulls the pointer
    [super dealloc];
  }

Next we create a storage object when the class instance is initialised. Add this to your class's init or viewDidLoad method.

 self.theseButtonsHaveBeenClicked = [[NSMutableDictionary alloc] dictionary]; // convenience method for creating a dictionary

And your updated buttonClicked: method should look more like this.

    -(void) buttonClicked:(UIButton *)sender {

         NSNumber *senderTagAsNum = [NSNumber numberWithInt:sender.tag];
         NSString *senderTagAsString = [[NSString alloc] initWithFormat:@"%@",senderTagAsNum];

         // this block adds to dict on first click, removes if already in dict
         if(![self.theseButtonsHaveBeenClicked objectForKey:senderTagAsString]) {
           [self.theseButtonsHaveBeenClicked setValue:senderTagAsNum forKey:senderTagAsString];
         } else {
           [self.theseButtonsHaveBeenClicked removeObjectForKey:senderTagAsString];                }
         [senderTagAsString release];
         NSLog(@"%@", self.theseButtonsHaveBeenClicked);
}

Upvotes: 3

Related Questions