grouser
grouser

Reputation: 628

Creating a Singleton NSMutableArray

I am trying to do a Singleton NSMutableArray, but the count function always shows 0 elements. I guess it is not receiving well the object.

This is the code that i have created.

//VariableStore.h
@interface VariableStore : NSObject
{
    NSMutableArray *pruebaGlobal;
}
@property (nonatomic, retain) NSMutableArray *pruebaGlobal;
+ (VariableStore *)sharedInstance;
- (NSMutableArray*)pruebaGlobal;
@end

//VariableStore.m
@implementation VariableStore
@synthesize pruebaGlobal;
+ (VariableStore *)sharedInstance
{
    // the instance of this class is stored here
    static VariableStore *myInstance = nil;

    // check to see if an instance already exists
    if (nil == myInstance) {
        myInstance  = [[[self class] alloc] init];
        myInstance.pruebaGlobal = [[NSMutableArray alloc] initWithCapacity:100];
    }
    // return the instance of this class
    return myInstance;
}

- (NSMutableArray*)pruebaGlobal{
    return pruebaGlobal;
}

@end

//ViewController.m

NSMutableArray *p = [[VariableStore sharedInstance] pruebaGlobal];
p = [NSArray arrayWithObjects:
                   [NSMutableArray arrayWithObjects:@"Sí", @"No", nil, nil, nil],
                   [NSMutableArray arrayWithObjects:@"Súbita", @"Fluctuante", @"Progresiva", nil, nil],
nil];

NSLog(@"%d", [[[VariableStore sharedInstance] pruebaGlobal] count]);

Upvotes: 0

Views: 1391

Answers (3)

Mathew
Mathew

Reputation: 1798

Setting aside the misuse of nil within your construction of arrays, your code simply does not ever add anything to the array you are getting the count of. Try this:

NSMutableArray *p = [[VariableStore sharedInstance] pruebaGlobal];
[p addObject:[NSMutableArray arrayWithObjects:@"Sí", @"No", [NSNull null], [NSNull null], nil]];
[p addObject:[NSMutableArray arrayWithObjects:@"Súbita", @"Fluctuante", @"Progresiva", [NSNull null], nil]];

As for the property you synthesize, you specify it as a retained property and then you explicitly define a getter for it but not a setter. If you declare a property as retained, you can either let the compiler take care of both getter and setter, or write both yourself, but not just one or the other. My suggestion, just remove the explicit getter: - (NSMutableArray*)pruebaGlobal from the header and implementation files.

Upvotes: 1

rmaddy
rmaddy

Reputation: 318874

The problem is that the synthesized ivar for the property will be named _pruebaGlobal. But your pruebaGlobal method is returning the pruebaGlobal ivar.

Your code should be update to be:

//VariableStore.h
@interface VariableStore : NSObject

@property (nonatomic, retain) NSMutableArray *pruebaGlobal;

+ (VariableStore *)sharedInstance;
- (NSMutableArray*)pruebaGlobal;

@end

//VariableStore.m
@implementation VariableStore

+ (VariableStore *)sharedInstance {
    // the instance of this class is stored here
    static VariableStore *myInstance = nil;

    // check to see if an instance already exists
    if (nil == myInstance) {
        myInstance  = [[[self class] alloc] init];
        myInstance.pruebaGlobal = [[NSMutableArray alloc] initWithCapacity:100];
    }

    // return the instance of this class
    return myInstance;
}

@end

You don't need an ivar or the @synthesize line anymore with the modern Objective-C compiler (Xcode 4.4 or later). Both will be generated for you.

You don't need to implement the pruebaGlobal method - it will be synthesized for you.

The other half your issue is that you assign a totally new array to the p variable which has no effect on the pruebaGlobal property. You need to assign p to the global if that is desired.

The line:

NSMutableArray *p = [[VariableStore sharedInstance] pruebaGlobal];

assigns your empty global array to p. You then do:

p = [NSArray arrayWithObjects:...

which assigned a new array to p. You then try to log the unmodified global.

You need to add:

[VariableStore sharedInstance].pruebaGlobal = p;

Upvotes: 0

Vincent Bernier
Vincent Bernier

Reputation: 8664

There is at least 2 problems with this part of the code :

NSMutableArray *p = [[VariableStore sharedInstance] pruebaGlobal];
p = [NSArray arrayWithObjects:
               [NSMutableArray arrayWithObjects:@"Sí", @"No", nil, nil, nil],
               [NSMutableArray arrayWithObjects:@"Súbita", @"Fluctuante", @"Progresiva", nil, nil], nil];

First : [NSMutableArray arrayWithObjects:@"Sí", @"No", nil, nil, nil]
arrayWithObjects can only take object and nil is not an object it is used to terminate the list of augments. If you want to insert the concept of nil into a NSArray you need to insert [NSNull null] which is a singleton object that exist specially for that use.

The Other problem is the use of p :
You are getting a reference to your NSMutableArray pruebaGlobal and then you replace the content of your pointer p with the address of an other new array. So p now point to a different object that pruebaGlobal.

The way to correct this would be like this :

NSMutableArray *p = [[VariableStore sharedInstance] pruebaGlobal];  
[p addObject:@"test object"];
NSLog(@"%d", [[[VariableStore sharedInstance] pruebaGlobal] count]);

Now you should have a count of 1.

Upvotes: 0

Related Questions