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

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.

Related

Objective-C define block after passing it to a method

Is it possible to define a block after passing it to a method? I want to do this so the code is in somewhat the order it runs in:
// Declare the block
void (^doStuffBlock)(void);
// Pass the block.
[self prepareToDoStuffWithCompletion:doStuffBlock];
// Define the block.
doStuffBlock = ^void() {
// Do stuff
};
doesn't work because inside prepareToDoStuffWithCompletion: the block doStuffBlock is nil.
you should first define the block then pass it to the method:
// Declare the block
void (^doStuffBlock)(void);
// Define the block.
doStuffBlock= ^void() {
// Do stuff
};
// Pass the block.
[self prepareToDoStuffWithCompletion:doStuffBlock];
You could use a typedef.
typedef void (^TypeName)(void);
- (void)bar:(TypeName)completion {
completion();
}
TypeName foo = ^() { /*...*/ };
[self bar:foo];
(My obj-c syntax might be a little rusty, but what you want to do is possible in both Objective-C and Swift.
https://stackoverflow.com/a/29580490/620197
http://goshdarnblocksyntax.com/
If you are certain that the method will run your doStuffBlock after you "define" it, what you could do is have your doStuffBlock capture a variable holding a second block with the real logic of what it should do. You can set the real-logic block after you create doStuffBlock, and you need to make sure that the variable holding the real-logic block is a __block variable, so that changes to the variable in the function scope are seen in the block scope.
__block void (^realLogicBlock)(void);
[self prepareToDoStuffWithCompletion:^{
if (realLogicBlock)
realLogicBlock();
}];
realLogicBlock = ^void() {
// Do stuff
};
You might have to be careful about retain cycles though -- if inside realLogicBlock, you capture a reference to self or to something that will reference the prepareToDoStuffWithCompletion: completion handler, you would have a retain cycle, in which case you may have to introduce a weak reference somewhere.
If you supply the completion handler closure, you are effectively saying “here is the closure I want you to use”.
If you are going to supply the closure later you would probably define a property:
#property (nonatomic, copy, nullable) void (^doStuff)(void);
Then, do not supply the closure when you call the method, but rather refer to this property:
- (void)prepareToDoStuff {
[self somethingAsynchronousWithCompletion:^{
if (self.doStuff) {
self.doStuff();
// if completion handler, you’d often release it when done, e.g.
//
// self.doStuff = nil;
}
}];
}
And, then you can call this method and supply the closure later:
[self prepareToDoStuff];
self.doStuff = ^{
NSLog(#"do stuff done");
};
A few additional considerations:
Make sure you synchronize your access to this doStuff property. E.g., in the above, I am assuming that the somethingAsynchronousWithCompletion is calling its completion handler on the main thread. If not, synchronize your access (like you would any non-thread-safe property in a multithreaded environment).
There is a logical race if you first call the method that will eventually call the block, and only later set that block property. Sometimes that is perfectly fine (e.g. maybe you are just trying to specify what UI to update when the asynchronous process finishes). Other times, the race can bite you. It depends upon the functional intent of the block property.
I would give the block property a name that better reflects its functional purpose (e.g. completionHandler or notificationHandler or didReceiveValue or whatever).

dispatch_once vs runtime check for once initialized property

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;
}

Clarification on an Objective-C Singleton Example

I'm just getting started on Objective-C and I came across this example on creating a singleton:
+ (BNRItemStore *) sharedStore
{
static BNRItemStore *sharedStore = nil;
if (!sharedStore)
sharedStore = [[super allocWithZone:nil] init];
return sharedStore;
}
I understand what's he's trying to do - which is to return the same instance if it's existing and create a new one if it's not. What bothers me is this line:
static BNRItemStore *sharedStore = nil;
Won't this line reset the sharedStore to a nil value everytime the method is called? I don't see how the method will be able to return the previously existing instance if this line always sets it to nil.
Thanks in advance.
This is an element which Objective-C inherits from standard C. Any variable with static storage duration (which the static type specifier explicitly declares) is only initialized once, and the c standard says that this happens before the program starts.
6.2.4 3) An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Note that it also mentions that if the variable with static storage duration is of 'pointer type', then it is automatically set to a NULL pointer (which is what nil is), so if you want, you can omit the = nil part of the declaration if you think it improves the readability of your function.
Won't this line reset the sharedStore to a nil value everytime the method is called?
Because sharedStore is static, it will be initialized (the = nil bit) the first time it is called. Subsequent calls will skip these instructions.
I don't see how the method will be able to return the previously existing instance if this line always sets it to nil.
Because it is static the variable and its value will remain in memory after the method exits.
Basically, you can think of this as a global variable, but it is accessible only to +sharedStore.

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.

Is there anything that can go wrong when I use static to implement a singleton?

I'm implementing a singleton class (and lets not get into the discussion if that is wrong or not). I have a method to get the instance of this class, which is lazily initialized:
+ (FFDataManager *)sharedDataManager {
static FFDataManager *dm = nil;
if (!dm) {
dm = [[FFDataManager alloc] init];
}
return dm;
}
Is there anything I should look out for when doing this using static (inside of the method) as opposed to creating a global variable? Is there anything that can go wrong, all tutorials on the Internet use a global variable.
My preferred singleton implementation looks like:
+ (MyClass *) sharedInstance {
static dispatch_once_t predicate = 0;
__strong static MyClass *shared = nil;
dispatch_once(&predicate, ^{
shared = [[self alloc] init];
});
return shared;
}
Using dispatch_once makes sure this is also thread safe. Your code would allocate twice when accessed by multiple threads at the same time.
To answer the original question (others have address the best way to do initialization):
Is there anything I should look out for when doing this using static (inside of the method) as opposed to creating a global variable?
No.
The difference is over visibility and not lifetime.
A global's (with or without static) lifetime is that of the application execution.
A global without static is visible throughout the whole application. From anywhere else it can be referenced by naming it in an extern statement.
A global with static is visible just in the containing compilation unit (which is typically a single file, but #import/#include can change that).
A variable declared within a function/method as static is a global which is only visible within that function/method.
If you're using a global in just one function what you've done is good - it limits the visibility to just where it is needed while keeping execution-lifetime. Any initializer is run once, just as for file-level globals.
What you create is a static local variable. Static local variables retain their value through successive method invocations. They can only be accessed from within the method which they are defined in. When apps start static local variables are set to 0 once.
So what you do in my opinion is with every call of sharedDataManager you declare a new static local variable and set it to nil. I don't think that's necessary or even good. And also every time if (!dm) checks dm it is nil because you set dm to nil the line before.
I'd go with the static global approach.
Edit:
Have a look at http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/