草庐IT

swift - 弱小的自己去哪儿了?

coder 2023-07-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 仍然存在,它将被内部闭包保活直到该闭包被解除分配。


回应:

Is a strong reference to a weak reference, a weak or strong reference?

弱引用被实现为可选值类型。因此,您不能直接对一个实例进行强引用——相反,您首先必须对其进行解包,然后对底层实例进行强引用。在这种情况下,您只是在处理强引用(就像我上面使用 strongSelf 的示例一样)。

但是,如果一个弱引用被装箱(这种情况发生在闭包捕获中——值类型将被放入一个堆分配的盒子中)——那么你确实可以对该盒子有一个强引用.这样做的效果相当于对原始实例的弱引用,你只是有一点不可见的额外间接。

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

关于swift - 弱小的自己去哪儿了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41991467/

有关swift - 弱小的自己去哪儿了?的更多相关文章

  1. ruby-on-rails - 如何测试自己对 Ruby/ROR 的了解? - 2

    是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby​​和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T

  2. ruby - 如何构建自己的自定义 session 存储类? - 2

    默认情况下,session存储在浏览器cookie(:cookie_store)中,但您也可以指定其他包含的存储之一(:active_record_store、:mem_cache_store或您自己的自定义类。请提供我构建自定义类的方式config.action_controller.session_store=:your_customer_class 最佳答案 MaurícioLinhares是正确的,但是,我想添加一些细节,因为我认为您需要实现哪些方法并不明显。你可以继承自ActionDispatch::Session::Ab

  3. 如何使用手机远程访问自己的电脑? - 2

    手机访问电脑后AnyViewer可以做什么? 您成功将手机连接到Windows电脑后,然后您可以做任何您想做的事情,例如:查看文件和运行应用程序。电源管理:在远程会话中,点击电源管理,您可以看到三个项目:锁定、重启和关机,供您在不同情况下管理计算机。如果您需要暂时离开远程会话,可以锁定计算机。如果计算机死机,您可以重新启动它,然后再次连接。如果您已完成计算机上的所有工作,您可以使用手机远程关闭它。更改图像质量:当电脑和手机的网络都处于良好状态时,您可以选择高图像质量以获得更好的体验。当网络状况不佳时,您可以选择低图像质量以获得更流畅的操作。     显示桌面:我们无法在手机上按Windows+

  4. ruby - OpenSSL 验证来自自己 CA 的证书 - 2

    大家好,感谢您花时间阅读本文。我需要验证由我自己的CA颁发的证书,我有一个证书。我怎样才能做相当于openssl的openssl验证-CAfile在Ruby代码中?OpenSSL的RDoc在这方面不是很有帮助。我试过:require'openssl'ca=OpenSSL::X509::Certificate.new(File.read('ca-cert.pem'))lic=OpenSSL::X509::Certificate.new(File.read('cert.pem'))putslic.verify(ca)但我得到:test.rb:7:in`verify':wrongargume

  5. ruby - 为什么我可以在 Ruby 中将一个 undefined variable 赋值给它自己并得到 nil? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Whya=aisnilinRuby?我们应该说,在Ruby中使用undefinedvariable是“奇怪的现象”。是这样的:#irbsessionfollows#foo#undefinedlocalvariableormethod'foo'bar#samefor'bar'foo=bar#stillsamefor'bar'foo=foo#nil-HUH?foo#isnowsettonil!?为什么我可以在Ruby中将一个undefinedvariable赋值给自身并得到nil?请注意,我在这里使用的是Ruby

  6. ruby - 如何在 heroku 中使用自己的 mysql 数据库服务器? - 2

    我想使用托管在我自己服务器上的mysql数据库。我已经更改了DATABASE_URL和SHARED_DATABASE_URL配置变量以指向我的服务器,但它仍在尝试连接到heroku的amazonaws服务器。我该如何解决? 最佳答案 根据Herokudocumentation,更改DATABASE_URL是正确的方法。Ifyouwouldliketohaveyourrailsapplicationconnecttoanon-Herokuprovideddatabase,youcantakeadvantageofthissamemec

  7. ruby-on-rails - RailsAdmin - 定制你自己的过滤器 - 2

    我正在使用https://github.com/sferik/rails_admin处理我的管理界面。可以根据此模型中存在的当前列(id、created_at等)过滤您的模型我希望能够为关联添加自定义过滤器。例如:当我探索“城镇”模型时,我希望能够仅显示具有一个或多个项目的城镇。我可以通过向城镇添加一个新列来做到这一点,称为has_projects作为bool值,当有1个或多个项目关联时将设置为true,但我觉得必须有一种更简洁的方法来制作您自己的自定义过滤器? 最佳答案 您可以尝试使用枚举。参见https://github.com

  8. ruby-on-rails - 是否有针对 Rails、Ruby、Erb 的 Xcode 语法着色?如果没有,我怎么能自己写一个? - 2

    Xcode的语法着色充其量只是很差,而textmate看起来不错,但我喜欢Xcode,因为我也用C++编程。我想将所有内容都放在一个地方并利用其他Xcode功能。有没有人已经这样做过或者有没有简单的方法来做到这一点? 最佳答案 你可以去Editor>SyntaxColoring>CheckHTMLanddoitagainforRuby 关于ruby-on-rails-是否有针对Rails、Ruby、Erb的Xcode语法着色?如果没有,我怎么能自己写一个?,我们在StackOverflo

  9. ruby - 为什么 Ruby 使用自己的安全导航运算符语法? - 2

    Ruby2.3.0引入了安全导航语法,它通过引入一个新的运算符来简化链式方法调用的nil处理,该运算符仅在先前语句的值不是nil。这是一个已经存在于C#、Groovy和Swift中的特性。例如inGroovy,语法是foo?.bar这基本上意味着结果值是foo.bar除非foo是null,在这种情况下返回值也是null因此不会抛出异常。还有C#(称为空条件运算符)和Swift(称为可选链接表达式)使用此表示法。所以语法在其他语言中似乎是相当标准的。现在,为什么在Ruby中语法是foo&.bar代替? 最佳答案 此答案基于thedis

  10. ruby-on-rails - 何时使用设计与创建我自己的身份验证 - 2

    如标题中所述,什么时候应该使用设计,什么时候应该实现我自己的身份验证。本质上,我想知道某些教程(例如this一个)中创建的身份验证是否安全可靠。如果我不需要电子邮件确认、可恢复性等(许多与Devise相关的“爵士乐”),帐户信息是否会像我创建自己的帐户一样安全?如果您仍然对我正在寻找的答案感到困惑–您是否应该尽可能/只要有帐户就使用Devise?或者它真的应该是一个决定吗?注意:我并不是专门指Devise,任何身份验证gem都可能被替换。 最佳答案 implementmyownauthentication任何时候您开始考虑是否应该创

随机推荐