在 heightForImageCellAtIndexPath 中 dispatch_once 的原因

Posted

技术标签:

【中文标题】在 heightForImageCellAtIndexPath 中 dispatch_once 的原因【英文标题】:Reason for dispatch_once in heightForImageCellAtIndexPath 【发布时间】:2015-04-03 08:37:40 【问题描述】:

当我搜索如何在 ios 中实现自动调整单元格大小时,我遇到了许多示例(herehere 和 here),其中包含 - (CGFloat)heightForImageCellAtIndexPath:(NSIndexPath *)indexPath 中的这个神秘代码

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

但我找不到这个 dispatch_once 背后的原因。我认为它的目的是节省一些记忆,但为什么是这种风格。为什么不定义属性并延迟加载它。

@property (nonatomic, strong) UITableViewCell sizingCell;

- (UITableViewCell)getSizingCell

  if (_sizingCell) return _sizingCell;

  _sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];

  return _sizingCell;

想知道它只是编码风格,或者这个 dispatch_once 实现背后有一些好处。

【问题讨论】:

【参考方案1】:

dispatch_once 的行为在名称中。它只做一次。

dispatch_once() 相对于其他方法的好处是速度更快。它在语义上也更清晰,因为dispatch_once() 的整个理念是“执行一次且仅一次”,这正是我们正在做的。

它是一个低级 GCD API,与任何其他方法相比,它提供了性能改进。

【讨论】:

另外,我们生活在一个多线程的世界中,dispatch_once 是线程安全的。保证多个线程同时调用dispatch_once只会执行一次block,所有线程都会等到执行完成后dispatch_once返回。即便是靠自己完成也不是太难,但是 dispatch_once 也非常快,而且真的很难做到。【参考方案2】:

如果您有多个表/集合视图实例,它只会节省内存,因为它们都会重用同一个实例。这更有效,尽管可能不经常使用。使用静态还可以将所有代码保存在一个位置。

您当然可以按照您建议的方式进行操作,并且 dispatch once 的好处并不大,但我会选择 dispatch once 路线(尽管您可以在模型中使用 dispatch once 来实现延迟加载) .

【讨论】:

【参考方案3】:

您使用了多少行代码?在多少个不同的地方?如果你想让它成为线程安全的,你有很多行代码,你没有?

dispatch_once 是众所周知的模式,每个人都理解。代码正好在它所属的地方。它有效,并且众所周知。这不是风格问题,而是使用众所周知的优越模式而不是随意、不安全且难以维护的方法的问题。

【讨论】:

我同意这种调度模式,将代码保留在它所属的位置。但是仍然怀疑延迟加载属性是多么随意、不安全和难以维护?

以上是关于在 heightForImageCellAtIndexPath 中 dispatch_once 的原因的主要内容,如果未能解决你的问题,请参考以下文章

秋的潇洒在啥?在啥在啥?

上传的数据在云端的怎么查看,保存在啥位置?

在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?

存储在 plist 中的数据在模拟器中有效,但在设备中无效

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据