0

one third party library uses my class initialisation:

ClassA *a = [[MyClass alloc] init]];

I need MyClass to be shared instance (aka singleton) but I can't modify 3rd party way of executing MyClass initialization

I was trying to override init method as following:

- (instancetype)init
{
    return [[self class] sharedInstance];
}

+ (LoopMeNativeEvent *)sharedInstance
{
    static LoopMeNativeEvent *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [LoopMeNativeEvent new];
    });
    return _sharedInstance;
}

but, unfortunately new causes alloc init to be executed.

Simplest way I know is to have two separate classes:

  • MyClass which will be initialised through alloc init
  • Separate MySharedClass which is singleton

Is there possibility achieve this having just one class?

Injectios
  • 2,777
  • 1
  • 30
  • 50
  • http://stackoverflow.com/questions/195078/is-it-possible-to-make-the-init-method-private-in-objective-c ? – Larme Jul 08 '15 at 13:15
  • omg... third party code will not be executed properly.. did you read question? or it's unclear? I need correct object to be returned by init, but I need it to be singleton – Injectios Jul 08 '15 at 13:16
  • I suspect you have a design issue. – Hot Licks Jul 09 '15 at 11:51
  • It's not mine design issue, sometimes, when you deal with 3rd party it happens – Injectios Jul 09 '15 at 14:12
  • Maybe instead of `[LoopMeNativeEvent new]`, you may call : `[[LoopMeNativeEvent alloc] initWithCustomParam:nil];`, and with `-(id)initWithCustomParam:(NSObject *)obj{self = [super init];if (self){}return self;}` It may avoid your issue. – Larme Jul 10 '15 at 08:40

2 Answers2

0

How about inheritance,

Create new class named ChildClass which inherit from MyClass and add the following two methods

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

    return sharedInstance;
}

- (id)init
{
    self = [super init];
    return self;
 }
  • As I said third party code executes MyClass init method... but I want to make sure just one instance of MyClass will be ever created. Do you think your solution make sense? – Injectios Jul 09 '15 at 14:11
0

Try this . It will definitely solve your problem.

- (instancetype)init
{
    return [[self class] sharedInstance];
}

+ (LoopMeNativeEvent *)sharedInstance {

    // structure used to test whether the block has completed or not
    static dispatch_once_t onceToken = 0;

    // initialize sharedObject as nil (first call only)
    static LoopMeNativeEvent *_sharedInstance = nil;

    // executes a block object once and only once for the lifetime of an application
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[LoopMeNativeEvent alloc] init];
    });

    // returns the same object each time
    return _sharedInstance;
}
Bhuvan Bhatt
  • 3,276
  • 2
  • 18
  • 23