0

I have two singleton classes which are defined like that

SingletonClassA.h

@interface SingletonClassA : NSObject

+ (SingletonClassA*) sharedInstance;

@end

SingletonClassA.m

#import "SingletonClassA.h"
#import "SingletonClassB.h"    

@implementation SingletonClassA

+ (SingletonClassA*) sharedInstance{
    static SingletonClassA* instance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [SingletonClassA];
        [[SingletonClassB shareInstance] methodB];
    });

    return instance;
}

@end 

SingletonClassB.h

@interface SingletonClassB : NSObject

+ (SingletonClassB*) sharedInstance;

@end

SingletonClassB.m

#import "SingletonClassB.h"
#import "SingletonClassA.h"

@implementation SingletonClassB

+ (SingletonClassB*) sharedInstance{
    static SingletonClassB* instance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [SingletonClassB];
        [[SingletonClassA shareInstance] methodA];
    });

    return instance;
}

@end 

When I build the project, everything seems to be nice but when I run on the simulator or on my phone, the application is not launching and an NSZombie error is displayed.

Class _NSZombie_BSXPCMessage is implemented in both ?? and ??.
One of the two will be used. Which one is undefined

I have tried to delete the app, clean the project and run again .. Same error. When I remove the import in one the two classes, it works fine.

Do you have an idea what did I do wrong ?

Thanks,

John smith
  • 355
  • 4
  • 17
  • It may be that the problem isn't so much circular dependency at the import stage as it is non-reentrant `dispatch_once`. – Phillip Mills Sep 19 '16 at 12:48
  • Yes you might be right. But what could I do to avoid that ? – John smith Sep 19 '16 at 12:54
  • Basically, change the design so that all your `sharedInstance` methods do is init the static object. When the objects need to interact with other objects, make it explicit. ("How" depends a lot on what uses these objects and what `methodA`/`methodB` do. – Phillip Mills Sep 19 '16 at 13:05
  • Well I have change the behavior of sharedInstance and now everything works fine. Thanks ! – John smith Sep 19 '16 at 13:27

1 Answers1

1

Could not reproduce your problem.

SingletonClassA.h

@interface SingletonClassA : NSObject

+ (SingletonClassA *) sharedInstance;
-(void)methodA;

@end

SingletonClassA.m

#import "SingletonClassA.h"
#import "SingletonClassB.h"

@implementation SingletonClassA

+ (SingletonClassA*) sharedInstance{
    static SingletonClassA* instance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [SingletonClassA new];
        [[SingletonClassB sharedInstance] methodB];
    });

    return instance;
}

@end

SingletonClassB.h

@interface SingletonClassB : NSObject

+ (SingletonClassB *) sharedInstance;

-(void)methodB;

@end

SingletonClassB.m

#import "SingletonClassB.h"
#import "SingletonClassA.h"

@implementation SingletonClassB

+ (SingletonClassB*) sharedInstance{
    static SingletonClassB* instance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [SingletonClassB new];
        [[SingletonClassA sharedInstance] methodA];
    });

    return instance;
}

@end

Importing classes in .m file should not introduce import cycle. You are not using new or alloc init. Why is that?

Rishab
  • 1,901
  • 2
  • 18
  • 34
  • As Phillip Mills said, it wasn't related to circular import. I was doing something wrong in methodA or methodB (I don't really know what) but now it's working fine. Thanks for your time too – John smith Sep 19 '16 at 13:28
  • The reason you could not reproduce the issue, is probably because you instantiated an instance of the singleton class in the shareInstance method, whereas the OP did not. In the OP's example, each instance was an unallocated, uninstantiated instance, aka NIL instance of the class, and thus the NSZombie condition. You solution is the correct one, and should have been marked as accepted. – Armand Jan 24 '18 at 05:39