Monstieur
Monstieur

Reputation: 8112

How to initialize a thread-safe variable in `init`?

I have the following code:

{
    NSObject *_object;
}

- (instancetype)init {
    if (self = [super init]) {
        _object = [[NSObject alloc] init];
    }

    return self;
}

- (NSObject*)object {
    return _object;
}

If the method object is called from a second thread after init has completed and returned, how do I know the assignment to _object within init will be visible and it's not actually returning an unassigned pointer?

What is the internal mechanism that guarantees this?

Upvotes: 0

Views: 241

Answers (2)

ahwulf
ahwulf

Reputation: 2584

Use dispatch_once. This is guaranteed to run only one time no matter how many threads there are. For example

+ (MyClass *)sharedInstance
{
    //  Static local predicate must be initialized to 0
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

Upvotes: 1

Joe
Joe

Reputation: 57179

The thread-safety of your code depends on how it is used, and how it is intended to be used is inherently thread-safe. You shouldn't be passing around partially constructed objects, therefore the allocation and initialization ([[... alloc] init] or new) should be confined to a single thread and then passed around to other threads.

Upvotes: 3

Related Questions