Segev
Segev

Reputation: 19303

How to keep data in a NSMutableArray

AAA.m:

- (void)keepCurrentArray:(id)object
{
     _currentTest=[[NSMutableArray alloc]init];
    [_currentTest addObject:@"one"];
    [_currentTest addObject:@"two"];
    [_currentTest addObject:object];
    NSLog(@"My Array is:%@",_currentTest);
}

Class BBB.m is passing objects to class AAA. Right now if i'm passing X to the above method so the array will be: one,two,X . Then i'll send it Y and the array will be one,two,Y instead of what i want to accomplish: one,two,x,one,two,y. Is that because I'm alloc and init _currentTest every time? How can I solve it?

Update: I had a few suggestions on how to solve this and none of them worked for me. I've created a new project with just the code in the answers and i'm still getting the same result when I try to add the second object i get: one, two, test instead of one,two,test,one,two,test

Upvotes: 0

Views: 120

Answers (4)

lnafziger
lnafziger

Reputation: 25740

This is happening because you are creating a new array every time that your method is called. Basically, you need to see if it has already been created, and only create it if needed. You can change your method to:

- (void)keepCurrentArray:(id)object
{
    if (!_currentTest) 
    {
        _currentTest=[[NSMutableArray alloc]init];
    }

    [_currentTest addObject:@"one"];
    [_currentTest addObject:@"two"];
    [_currentTest addObject:object];
    NSLog(@"My Array is:%@",_currentTest);
}

EDIT:
In addition to the above problem, you also have this code which needs to be corrected (comments removed):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ViewController *kios = [ViewController new];
    [kios keepCurrentArray:@"Test"];
}

This code creates a new instance of ViewController every time that you click on a row in the table. Because you are creating a new instance instead of reusing the old one, you start with an empty array each time. In order to keep adding to the same array, you need to keep using the same view controller.

In order to do this, you need to add a declared property to your .h file, similar to your currentTest declared property:

@property (strong,nonatomic) ViewController *kios;

Then, change your action so that you only create a new view controller if needed (the first time) and then reuses it after that:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!_kios)
    {
        _kios = [ViewController new];
    }

    [_kios keepCurrentArray:@"Test"];
}

Upvotes: 1

Vincent Bernier
Vincent Bernier

Reputation: 8664

Well you need to have a property for that _currentTest if you want to be able to keep it around between method call.

Put this in your .h file
@property (nonatomic, copy) NSMutableArray * currentTest;

And this in hour .m file

- (NSMutableArray *)currentTest
{
    if (!_currentTest)
        _currentTest = [[NSMutableArray alloc] initWithCapacity:11];

    return _currentTest;
}

- (void)keepCurrentArray:(id)object
{
    [self.currentTest addObject:@"one"];
    [self.currentTest addObject:@"two"];
    [self.currentTest addObject:object];
    NSLog(@"My Array is:%@", self.currentTest);
}

I Just try the code you've put on drop box and it's working exactly as it is suppose to, the array keeps it's value and everything,
BUT

Exactly as it is suppose to is not what you are trying to achieve

Your problem is not in AAA.m, your problem is in BBB.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ViewController *kios = [ViewController new];
    [kios keepCurrentArray:@"Test"];
    [kios keepCurrentArray:@"Test2"];

}

I took the liberty of adding the @"test2" to the code you've send. If you run it you will see that your array still exist when the second call is made.
The REAL problem here is that you are creating a NEW ViewController each time. A brand new one, it is normal that it is empty (clean), it's a new one.
If I buy a note pad monday and fill it up, I don't expect when I'm buying an other one on friday to be already fill with the stuff I've wrote on monday in the previous one.
But this is exactly that behaviour that you are expecting from your ViewController.

You need to store your NSMutableArray in an other object that doesn't get destroy and created over and over again.

Upvotes: 1

Anoop Vaidya
Anoop Vaidya

Reputation: 46533

_currentTest=[[NSMutableArray alloc]init]; in a method is never a good thing!!!

As per naming convention it seems to be a property to the AAA Class. So for property, the alloc+init should be either in init or awakeFromNib. So that if is initialized just once.

However in some situations init is called more than once then your previous values are lost and new set are added.

So what you can do is make another class and put this _currentTest Array there and make it static and use it here. I hope this will work fine. And make sure in the init method of that class it is initialized just once, as :

//**this is not compiled and checked may contains typo and errors**

@implementation Storage

static NSMutableArray *yourStaticArray;

-(id)init{
    self = [super init];
    if (self) {
        if (!yourStaticArray) {
            yourStaticArray=[NSMutableArray new];
        }
    }
    return self;
}

-(void)addYourStaticArray:(NSString *)val{
    [yourStaticArray addObject:val];
}


-(NSArray *)yourStaticArray {
    return yourStaticArray ;
}

@end

Upvotes: 1

TheAmateurProgrammer
TheAmateurProgrammer

Reputation: 9392

Yes, it's because that you're alloc and init-ing every time you run that method. Instead, put _currentTest = [[NSMutableArray alloc] init]; in AAA.m's init method.

AAA.m

-(id)init
{
    if ((self = [super init]))
        _currentTest = [[NSMutableArray alloc] init];
    return self;
}

- (void)keepCurrentArray:(id)object
{
    [_currentTest addObject:@"one"];
    [_currentTest addObject:@"two"];
    [_currentTest addObject:object];
    NSLog(@"My Array is:%@",_currentTest);
}

Upvotes: 2

Related Questions