Update: While this does work, the Apple documentation says that this behavior is undefined:

The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.

Update II: Using OSMemoryBarrier() makes this behavior fully defined.

Ben Stiglitz wrote in with a suggestion. Using OSMemoryBarrier() in the initializer of your object makes sure that it is globally visible (i.e., from any thread) before any code that references it executes.

Original Post:
Every use of dispatch_once that I’ve seen across the web has been for setting up singletons by using a static token to make sure the initialization code only runs once per session of the app.

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

This is a great technique, but I’ve been looking for a way to use dispatch_once once per instance instead of once per class, but it’s no really clear how to adapt the singleton technique for a per-instance technique. I hacked around with a new project today and figured it out. It ends up being about as straightforward as you would expect.

@interface MyClass ()

@property (nonatomic, assign) dispatch_once_t onceToken;

@end

Declare a dispatch_once_t single use token in your class’s extension, and use that for running the code you only want to run once (such as initialization).

- (void) setupThing {  
	dispatch_once(&_onceToken, ^{  
		//set up thing  
	});  
}   You can now call this method as many times as you want (per instance) from any thread, and it will only be run once.