Sang
Sang

Reputation: 4456

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

Upvotes: 1

Views: 290

Answers (1)

Rob Napier
Rob Napier

Reputation: 299355

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

Upvotes: 1

Related Questions