Mark Molina
Mark Molina

Reputation: 5077

return singleton with ARC

I've finally updated my old project to ARC and everything works fine except of my 3 singleton classes. For now it works if I just exclude these 3 classes from ARC but I actually want them to work using ARC.

My old code was like:

static void * volatile session = nil;

+ (DNWSession*)session
{
    while(!session)
    {
        DNWSession *tmpSession = [self new];

        if(!OSAtomicCompareAndSwapPtrBarrier(0, tmpSession, &session))
            [tmpSession release];
    }

    return session;
}

To use ARC I converted my code to:

static void * volatile session = nil;

+ (DNWSession*)session
{
    while(!session)
    {
        DNWSession *tmpSession = [self new];

        if(!OSAtomicCompareAndSwapPtrBarrier(0, (__bridge void *)(tmpSession), &session))
    }

    return (__bridge DNWSession *)(session);
}

But when calling session on this class from the main thread my app crashes and gives me a EXC_BAD_ACCESS (code=1, address= xxx) and I don't really know why this is happening.

How can I make this part work with ARC?

EDIT

I've tried just creating a new session without the if statement but that also gives me the same error

+ (DNWSession*)session
{
    while(!session)
    {
        session = (__bridge void *)([self new]);
        /*DNWSession *tmpSession = [self new];

        if(!OSAtomicCompareAndSwapPtrBarrier(0, (__bridge void *)(tmpSession), &session))
            ;*/
    }

    return (__bridge DNWSession *)(session);
}

Upvotes: 0

Views: 127

Answers (1)

zaph
zaph

Reputation: 112857

Create the singleton with dispatch_once_t:

+ (instancetype)sharedInstance {
    static dispatch_once_t once;
    static id _sharedInstance = nil;
    dispatch_once(&once, ^{
        _sharedInstance = [[self alloc] init];
    });

    return _sharedInstance;
}

Upvotes: 3

Related Questions