0

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);
}
Mark Molina
  • 5,057
  • 8
  • 41
  • 69
  • It looks like your new code is missing a statement after the `if`. – Sergey Kalinichenko Jun 02 '14 at 12:59
  • Hmm.. So Xcode just removed the release line. I see. So the whole OSAtomicCompareAndSwapPtrBarrier part becomes useless in ARC? – Mark Molina Jun 02 '14 at 13:01
  • 1
    I don't think it has become completely useless, but it is definitely not too useful in this case. This whole solution has been somewhat suboptimal to begin with, because it could lead to creating multiple instances of `[self new]` of which only one would "survive" in the end. This is because in this approach the new instance is constructed "proactively". I prefer [this implementation](http://stackoverflow.com/a/145395/335858) of singleton in Objective-C, which is free of this shortcoming. – Sergey Kalinichenko Jun 02 '14 at 13:06
  • That's why I doesn't love ARC. Try `__bridge_retained` instead `__bridge` – Cy-4AH Jun 02 '14 at 13:07

1 Answers1

3

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;
}
zaph
  • 111,848
  • 21
  • 189
  • 228