dispatch_once vs runtime check for once initialized property - objective-c

What is the difference between dispatch_once and using runtime conditional check for the property that requires only once initialization
Method 1: runtime checking
- (MyProp *)myProp{
if (!_myProp){
_myProp = [[MyProp alloc] init];
}
return _myProp;
}
Method 2: use dispatch_once
- (MyProp *)myProp{
dispatch_once_t once;
dispatch_once(&once, ^{
_myProp = [[MyProp alloc] init];
}
return _myProp;
}
I guess that method 2 is somehow faster but not really sure.
Could anyone give me any deal?
Thanks

dispatch_once is thread safe. So if two threads call myProp for the first time simultaneously, dispatch_once ensures only one initializes the variable. Method 1 may initialize the variable twice, and could even corrupt memory such that the reference is invalid. Once the property has been initialized, these behave identically.
Method 2 is actually slightly slower than Method 1, particularly during the first initialization. But in the usual case (reading after initialization), it is extremely close (possibly identical) in performance. If you want a much more in-depth exploration of how it works and why, see Mike Ash's Secrets of dispatch_once.
Note that your Method 2 code is incorrect. You've made once an automatic local variable. It needs to be static or dispatch_once can't do its job. What you meant was:
- (MyProp *)myProp{
static dispatch_once_t once; // <--- this "static" is critical
dispatch_once(&once, ^{
_myProp = [[MyProp alloc] init];
}
return _myProp;
}

Related

Are my Objective-C singletons thread safe?

I've been reading around and its hard to get a clear feel if I have written a thread safe implementation here.
My getter looks like
+ (MySingleton *)getSingleton
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[MySingleton alloc] init];
});
return singleton;
}
And my setter is:
+ (void)updateSingleton:(MySingleton *)newSingleton
{
#syncronized(self) {
singleton = newSingleton;
}
}
No, that isn't thread safe. Your exclusion mechanism between your two modification methods are not the same. dispatch_once has nothing to do with #synchronized in any way.
Beyond that a singleton must never be replaced by definition. A singleton can come into existence at any time and, once it does, it never, ever, goes away.
Also, getSingleton should be sharedInstance or some similar objective-c standard moniker. Methods should never be prepended with get unless they are returning stuff by reference.

Objective C - What makes a static variable initialize only once?

I came from another programming language. I can understand singleton pattern. But I got confusion in ObjectiveC's Singleton Implementation.
Actually, I understand the lifetime of a static variable. But What makes a static variable initialize only once?
#implementation MyManager
+(instancetype)sharedInstance {
// structure used to test whether the block has completed or not
//Doubt 1 - If this method called second time, how it is not reset again to 0. How it is not executed second time?
static dispatch_once_t p = 0;
// initialize sharedObject as nil (first call only)
//Doubt 2 - If this method called second time, how it is not reset again to nil, How it is not executed second time?
__strong static MyManager * _sharedObject = nil;
// executes a block object once and only once for the lifetime of an application
dispatch_once(&p, ^{
_sharedObject = [[self alloc] init];
});
// returns the same object each time
return _sharedObject;
}
#end
In computer programming, a static variable is a variable that has been allocated statically so that its lifetime or "extent" extends across the entire run of the program.
https://en.wikipedia.org/wiki/Static_variable
The call to dispatch_once makes it initialize only once.
dispatch_once takes a pointer to a static memory location. It does effectively the following:
lock location; if anyone else has locked location, block until we can
if (location is unset) {
do_thing
set location
}
unlock location
But it does this in a much faster way that doesn't require a real lock (it does require a special CPU instruction, though, called "compare and swap.") If you want more details, see Mike Ash's excellent explanation. But for most uses, you can just accept that dispatch_once, if used correctly, will only run once per execution of the program.

Difference creating Singleton by class method and instance method

What are the implications of creating a singleton class with:
+ (id)sharedCoordinator {
static MyCoordinator *sharedCoordinator = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedCoordinator = [[self alloc] init];
});
}
or as an instance method in the Application Delegate with class method:
- (CoreDataHelper *)cdh {
if (!_coreDataHelper) {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
});
[_coreDataHelper setupCoreData];
}
return _coreDataHelper;
}
I have seen them both used, and would like to learn how they affect performance, simple code, debugging, etc.
The main difference is that the second code snippet has an error: when cdh is accessed concurrently from multiple threads, there is a possibility of [_coreDataHelper setupCoreData] being called twice.
This would happen if multiple threads arrived at cdh at the time when _coreDataHelper is nil. Only one of these threads would proceed to make the [CoreDataHelper new] call, yet all threads would end up in the setupCoreData method.
The proper way of doing initialization is to place the setup call into the block, and make the call unconditional:
- (CoreDataHelper *)cdh {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
[_coreDataHelper setupCoreData];
});
return _coreDataHelper;
}
Now the two snippets look almost identical. The only difference is that the first snippet uses a method-static variable to store the singleton, while the updated second snippet "piggybacks" on the instance of app delegate.
This does not create any performance differences worth discussing. The biggest difference is that the first snippet lets you access the singleton without creating an additional dependency on the app delegate, which is a good thing: this avoids "polluting" your app delegate with code that is not directly relevant to the application state.
The first allows the Singleton class to be re-used in other places.
The second makes the single instance private to the app delegate.
Generally the first option is better (IMHO.) It allows you to reuse the single instance in a structured way anywhere in your code.
The second option can provide a guarantee of being a single instance, privately accessible in one place. That is probably useful in some circumstances, but it isn't really a Singleton. You could make this a public property on the AppDelegate, but then why not use a Singleton class?
As for performance considerations, they should be negliable. The only one I can think of is the slight extra overhead in the runtime caused by having an extra class object in your code.

Singleton objective c clarification

as I continue my studies the book implemented a singleton.
I understood the reason why use it but I just wanted some clarification regarding the code.
+ (BNRItemStore *)defaultStore
{
static BNRItemStore *defaultStore = nil;
if(!defaultStore)
defaultStore = [[super allocWithZone:nil] init];
return defaultStore;
}
In the line static BNRItemStore * defaultStore = nil; until the return statement.
My question is; all the time that I call this class, [[BNRItemStore defaultStore] someMethod]; in another class or part of the app, the defaultStore variable will be set to nil?
Cheers
It's important to understand that the static keyword has two effects. One is that it makes that variable exist before the method is called, and persist after it returns, so that it will be available for the next call. The other effect is more subtle -- the "assignment" that initializes the static variable is executed when the code is loaded, not when the method is called. So it does not get reinitialized on every call.
But since the variable exists "outside" of the method, it's name should be unique -- don't use the same name in another singleton in this class or another one.
That's the initializer of a variable with static storage duration. The value will be set when the executable is loaded into memory.
Note that its not necessary to explicitly set the value to nil as all variables with static storage duration are automatically set to 0.
For function-static variables the line
static BNRItemStore *defaultStore = nil;
is not an assignment. Rather, it is static initialization, which happens only once - the first time the code goes through your function. In subsequent invocations the value will not be nil, because you assign a non-nil value to it.
Your implementation is safe in single-threaded environments. For concurrent environments you would need to add some form of synchronization.
Static variables are initialized just the one time when the function/method is first called. After that, you can basically pretend the line doesn't exist.
Apple recommends something like the following
+ (BNRItemStore *)defaultStore
{
static BNRItemStore *defaultStore = nil;
static dispatch_once_t done;
dispatch_once(&done,
^{ defaultStore = [BNRItemStore alloc]init];});
return defaultStore;
}
The above code assumes ARC - If not using ARC you would have to define do nothing retain, release, autorelease, and dealloc methods.

Memory management with block and ARC, leak?

I need to know if I do it correctly. The application is running OK but I'm not sure I get the lifecycle correctly (leak ?).
Note: Instrument see no leak.
The code of a method aaa: of some class A:
- (void) aaa {
NSString *path = ...something...;
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
// using path
[self somethingElseWith:path];
}];
[self.aQueue addOperation:theOp];
}
So I create a block to put on aQueue (NSOperationQueue*). The goal is to offload from the main thread the long running somethingElseWith: method, so that the GUI continue to be responsive.
Inside the block I reference the local var "path" that will be out of scope at the end of the aaa: method.
If I read the doc correctly, the block will do a retain on 'path'. But is ARC inserting a release at the end of this block implicitly ? Would be logical and nice.
Or should I declare 'path' as __block and assign it to nil at the end of my block ? (manual...)
Not sure I understand how to use __weak in this context.
The path variable is fine. You may however need to avoid a retain cycle by using a weak reference to self. If aQueue is a strong reference there may be a retain cycle causing self never to be released.
Solution:
- (void) aaa {
NSString *path = ...something...;
__weak id self_ = self;
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
// using path
[self_ somethingElseWith:path];
}];
[self.aQueue addOperation:theOp];
}
Make sure the operation does not get called after the class should no longer exist.
The block will automatically handle memory management for any locals from the enclosing scope. You don't have to worry about retain/release pairs in this case. Note, though that path will be const within the block's scope. If you need pathto be mutable within the block, use the __block attribute.
The different ways a block handles variables is described in detail here: Blocks and Variables