5

When I search for how to implement auto sizing cell in iOS I come across many examples (here here and here) with this mysterious code in - (CGFloat)heightForImageCellAtIndexPath:(NSIndexPath *)indexPath

static CommentedItemCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
});

But I can't find a reason behind this dispatch_once thing. I think its aim to save some memory, but why this style. Why not define property and lazy load it.

@property (nonatomic, strong) UITableViewCell sizingCell;

with

- (UITableViewCell)getSizingCell
{
  if (_sizingCell) return _sizingCell;

  _sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];

  return _sizingCell;
}

Want to know its just coding style or there is some benefit behind this dispatch_once implementation.

Community
  • 1
  • 1
sarunw
  • 8,036
  • 11
  • 48
  • 84

3 Answers3

4

The behavior of dispatch_once is in the name. It does something once and only once.

The benefit of dispatch_once() over the other approach is that it's faster. It's also semantically cleaner, because the entire idea of dispatch_once() is "perform something once and only once", which is precisely what we're doing.

It's a low level GCD API, which provides performance improvements over any other approach.

Sanjay Mohnani
  • 5,947
  • 30
  • 46
  • Also, we live in a multithreaded world, and dispatch_once is thread safe. It's guaranteed that multiple simultaneous calls to dispatch_once from multiple threads will only execute the block once, and all threads will wait until execution is complete before dispatch_once returns. Even that is not too hard to accomplish on your own, but dispatch_once is also extremely fast, and that is really tough to pull off. – Sanjay Mohnani Apr 03 '15 at 08:52
2

It will only save memory if you have multiple instances of your table / collection view because they will all reuse the same instance. This is more efficient, though likely not often used. Using the static also keeps all the code in one place.

You certainly can do it the way you propose, and the benefits of the dispatch once aren't huge, but I'd choose the dispatch once route (though you could use dispatch once in your model to achieve th lazy load).

Wain
  • 118,658
  • 15
  • 128
  • 151
0

How many lines of code did you use? In how many different places? You many lines of code if you wanted to make it thread safe, which you didn't?

dispatch_once is a well-known pattern that everyone understands. The code is exactly in the place where it belongs. It works, and it is known to work. This isn't a question of style, this is a question of using a well-known and superior pattern instead of a haphazard, unsafe, and hard to maintain method.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • I agree on this dispatch pattern keep the code where it belong. But still doubt on how lazy load property is haphazard, unsafe and hard to maintain? – sarunw Apr 03 '15 at 10:24