当前位置: 首页 > 面试题库 >

虚弱的自我会去哪里?

隗驰
2023-03-14
问题内容

我经常这样做

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   beep()
}

在一个应用程序中,我们经常这样做

tickle.fresh(){
    msg in
    paint()
}

但如果你做 这个

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   tickle.fresh(){
      msg in
      paint()
   }
}

当然,你必须做 这个

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
   tickle.fresh(){
      msg in
      self?.paint()
   }
}

或者,也许

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
   tickle.fresh(){
      [weak self] msg in
      self?.paint()
   }
}

也许这

let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
   tickle.fresh(){
      [weak self] msg in
      self?.paint()
   }
}

所有这三个建议 似乎都 可以正常工作。这里的完整含义是什么?那该怎么办?强引用是弱引用,弱引用还是强引用?生存还是毁灭?这就是问题所在!


问题答案:

首先,请注意DispatchQueue.main.asyncAfter,由于闭包将在 某个
时刻执行,因此您通常不必担心使用保留周期。因此,无论您是否弱捕获了self,都不会创建一个永久的保留周期(假设tickle.fresh也没有)。

是否[weak self]在外部asyncAfter闭包上放置捕获列表完全取决于是否要self保留直到调用闭包(设置时间之后)。如果self在调用闭包之前不需要保持活动状态,请放入[weak self],如果这样做,则不要放入。

是否[weak self]在内部闭合上放置一个(传递给的tickle.fresh)取决于您是否已经弱捕获self外部闭合。如果没有,则可以放置[weak self]以防止内部封闭保留它。但是,如果外部封闭已被弱捕获self,则内部封闭将 已经 具有弱引用self,因此添加[weak self]到内部封闭将无效。

因此,总结一下:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { msg in
      self.paint()
   }
}

self 将由外部和内部封闭保留。

DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { msg in
      self?.paint()
   }
}

self 不会被任何一个关闭保留。

DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

与上述相同,[weak self]用于内部封闭件的附加件没有作用,因为self外部封闭件已经很弱地捕获了附加件。

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
   tickle.fresh { [weak self] msg in
      self?.paint()
   }
}

self 将由外部封闭物保留,而不由内部封闭物保留。

当然,可能您不想self被外部闭包保留,但是您 确实
希望被内部闭包保留。在这种情况下,您可以在外部闭包中声明一个局部变量,以便持有对的强引用self,然后才能在内部闭包中进行捕获:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
   guard let strongSelf = self else { return }
   tickle.fresh { msg in
      strongSelf.paint()
   }
}

现在,self外部闭包将不会保持活动状态,但是一旦调用它(如果self仍然存在),内部闭包将使其保持活动状态,直到该闭锁被释放为止。

回应:

强引用是弱引用,弱引用还是强引用?

弱引用作为值类型的可选实现。因此,您不能 直接
引用一个实例,而是必须先对其进行拆包,然后再对该实例进行引用。在这种情况下,您只是在处理强大的参考(与我上面的示例完全一样strongSelf)。

但是,如果将弱引用 装箱
(在闭包捕获中发生–值类型将放入堆分配的盒子中)–那么您确实可以对该盒子有强引用。这样做的效果等同于对原始实例的弱引用,您只是看不见了一些额外的间接引用。

实际上,这 正是 在外部闭合弱捕获self而内部闭合“强烈捕获”弱引用的示例中发生的情况。结果是两个闭包都不保留self



 类似资料:
  • 轻应用-审批(如果没有点击“添加”) 审批支持手机端和电脑端,电脑端操作与手机端相同。

  • 1.手机端 手机轻推-通讯录-我的企业-管理-设置新人邀请 手机端上可以处理一些简单的管理操作如设置新人申请包括邀请权限、邀请方式、审核方式的设置,以及处理新成员/访客加入团队申请。 2.电脑端 登录企业管理网页web.qingtui.com/tms或者登录电脑端轻推-企业管理-输入轻推账号和密码-进入企业管理(若您同时是多个企业的管理员,选择您想要管理的企业)。

  • 登录团队管理web.qingtui.cn/tms或通过电脑端轻推进入企业管理-选择需要管理订阅号的团队。

  • mysql锁怎么实现的 可重复读会有什么不好的地方 java怎么屏蔽cpu架构差异的(说了个英文我以为是java虚拟机内存布局,说我回答的不是一个东西) 线程池怎么确定核心线程数大小,有哪些依据 hashmap扩容,什么时候扩容(好像是负载因子 忘记了)为什么2的n次方(少回答了个,扩容时候作用)

  • 手机轻推-轻应用-考勤打卡(如果没有点击“添加”) 备注:目前考勤打卡轻应用只能在手机上操作和管理

  • 企业管理-企业信息(企业名称、企业号、创建时间、企业认证、使用情况)