0

I have created a singleton class in Objective C. Like the one below:

@interface SingletonClass : NSObject{
   NSMutableArray *instanceArray;

}

@property(nonatomic,retain)NSMutableArray *instanceArray;

+(SingletonClass*)sharedInstance;

@end

@implementation SingletonClass
@synthesize instanceArray;

static SingletonClass *sharedInstance =nil;

+(SingletonClass*)sharedInstance
{
    if(sharedInstance==nil){
        sharedInstance=[[super allocWithZone:NULL]init];
    }
    return sharedInstance;
}


-(id)init{
    self=[super init];
    if(self){
        instanceArray=[[NSMutableArray alloc]init];
        [instanceArray addObject:@"One"];
        [instanceArray addObject:@"Two"];
    }
    return  self;
}

+(id)allocWithZone:(NSZone *)zone{   
    return [self sharedInstance];
}

@end

I know it can be accessed from anywhere with the following piece of code:

    SingletonClass *singletonObject=[SingletonClass sharedInstance]; 

And the instanceArray can be accessed anywhere by singletonObject.instanceArray.

Now my question is, is is possible to modify the array by adding new objects to it ? Will that be persisted ? Because i tried to add an object from one class

    [singletonObject.instanceArray addObject:@"Three"];

When i checked the array contents from another class, the array consisted of only two values which are initialized by default. The value which i added from another class didnt show up. What could be the problem ? Am I missing something here ? Please help.

tia
  • 9,518
  • 1
  • 30
  • 44
stack2012
  • 2,146
  • 2
  • 16
  • 23

3 Answers3

3

Drop the allocWithZone: implementation entirely. It is prone to error and a distinctly odd thing to do. The reality is that if you have code that is using your singleton class and not going through sharedInstance then that code is broken. Attempting to hide that brokenness is just going to cause pain later.

Just do this one:

+(instancetype)sharedInstance
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[SingletonClass alloc] init];
  });
  return sharedInstance;
}

If you aren't seeing updates to the array in your other class, then there is some other bug.

M Jesse
  • 2,213
  • 6
  • 31
  • 37
bbum
  • 162,346
  • 23
  • 271
  • 359
1

Your implementation of allocWithZone: is never called because you are calling the [super allocWithZone:], also i don't think you need this method. i would change your class method with this:

+(instancetype)sharedInstance
{
    if(sharedInstance==nil){
        sharedInstance = [[SingletonClass alloc]init];
    }
    return sharedInstance;
}

and if you want to be more secure that you are not going to create another instance of your object use dispatch_once:

+(instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[SingletonClass alloc] init];
    }
    return sharedInstance;
}
bbum
  • 162,346
  • 23
  • 271
  • 359
bago
  • 108
  • 1
  • 9
  • OP's `allocWithZone:` wasn't supposed to be called by his implementation because it'd be an infinite loop.... – bbum May 17 '13 at 14:42
-4

I think that you forgot the ! before self in init method :

-(id)init {

    self = [super init];
    if(!self) {
        instanceArray=[[NSMutableArray alloc]init];
        [instanceArray addObject:@"One"];
        [instanceArray addObject:@"Two"];
    }
    return  self;
}

That's why each time you get a new instance of your singleton

Shamanoid
  • 23
  • 5