Swift 4.x/5.x 中是不是有多个全局变量副本?如果是这样,你如何阻止它?

Posted

技术标签:

【中文标题】Swift 4.x/5.x 中是不是有多个全局变量副本?如果是这样,你如何阻止它?【英文标题】:Are there multiple copies of Global variables in Swift 4.x/5.x? If so, how do you stop that?Swift 4.x/5.x 中是否有多个全局变量副本?如果是这样,你如何阻止它? 【发布时间】:2019-11-23 00:14:47 【问题描述】:

在这个问题上抓了很多头,但无法弄清楚 - 希望在我所有的头发都消失之前有人可以提供帮助或解释!任何建议或解决方案都将不胜感激。提前为这个问题的长度道歉

我的应用程序使用全局变量(好吧,也许不是最好的设计,但这不是重点)跟在它的 tableView 中显示的内容,结构或类的数组,这似乎无关紧要

 class Section 
     var sectionDate : String
     var sectionData : [CeuEvent]
     var isVisible : Bool = false 
     // added these to verify isVisible is being changed.
         willSet(isVisible) 
             print("About to set isVisible to \(isVisible)")
         
         didSet 
             if isVisible !=  oldValue  
                 print("Added \(isVisible) - \(oldValue)")
             
         
     
     init(sectionDate: String, sectionData: [CeuEvent], isVisible: Bool) 
         self.sectionDate = sectionDate
         self.sectionData = sectionData
         self.isVisible = isVisible
     
 
 var sections : [Section] = []

tableView 部分一开始都是折叠的 (isVisible == false)

tableView 部分标题有一个可点击的标签,标签值 = 部分编号和附加的手势识别器。识别器的操作按预期被调用:

在 TapGestureRecogniser 部分[label.tag].isVisible 中检查了 isVisible 值,正如预期的那样,它是 false。

 (lldb) po sections
 ▿ 1 element
   ▿ 0 : <Section: 0x600002181dd0>

 (lldb) po sections[0]
 <Section: 0x600002181dd0>

 (lldb) po sections[0].isVisible
 false

然后 isVisible 被切换 - 并在调试器中验证

 (lldb) po sections[0].isVisible
 true

tableView.reload() 被调用。

在tableView(_tableView: UITableView, numberOfRowsInSection section: Int)中,section[0].isVisible被测试

 (lldb) po sections
 ▿ 1 element
   ▿ 0 : <Section: 0x6000021d2ee0>

 (lldb) po sections[0]
 <Section: 0x6000021d2ee0>

它又回到了虚假状态。

 (lldb) po sections[0].isVisible
 false

似乎 var 部分:[Section] 现在位于不同的内存地址,可能是在 TapGestureRecogniser 中更新 isInvisible 时的副本,并在响应 numberOfRowsInSection() 时返回原始地址,如其内存地址所示:

设置为true后TapGestureRecogniser动作中section和section[0]的内存值:

 (lldb) po countLabel.tag
 0

 (lldb) po sections
 ▿ 1 element
   ▿ 0 : <Section: 0x600001805d40>

 (lldb) po sections[0]
 <Section: 0x600001805d40>

 (lldb) po sections[0].isVisible
 true

in numberOfRowsInSection() - isVisible 恢复为 false

 (lldb) po sections
 ▿ 1 element
   ▿ 0 : <Section: 0x6000018cc480>

 (lldb) po sections[0]
 <Section: 0x6000018cc480>

 (lldb) po sections[0].isVisible
 false

var 部分是否包装在结构中并设为静态或什至添加到 AppDelegate 并适当访问都没关系 - isVisible 值不断变回 false。

【问题讨论】:

显示更新部分的代码。将didSet 添加到sections 并设置断点以找出您将新数组分配给它的位置 请创建一个最小的项目来重现问题并显示它的整个代码。 【参考方案1】:

感谢您的建议。但我认为这不能说明问题。

在调用 tapnotificaton 并在该部分的结构中更新可见之后,我认为通过调用重新加载该部分可能很重要

tableView.reloadSections([countLabel.tag], with: .automatic)

Doc 说“使用给定的动画效果重新加载指定的部分。”

认为这是正确的做法,并且它可能会执行函数名称所暗示的操作,通过仅为指定部分调用 numberOfRowsInSection() 重新加载指定部分,在这种情况下,是过渡中涉及的一个部分。

但是,不,这似乎触发了一个完整的 tableView 重新加载,它调用 numberOfSections() 并导致使用可见的默认值为 false 以及其他数据重建节数组。

再次感谢您的浏览。

现在想办法保持每个部分的可见性状态,而不会在每次重新加载时破坏它。可能必须添加/删除行。

欢迎和赞赏任何建议。

【讨论】:

请在对原始问题的编辑中包含任何表明您的推理的事后想法,而不是作为答案。

以上是关于Swift 4.x/5.x 中是不是有多个全局变量副本?如果是这样,你如何阻止它?的主要内容,如果未能解决你的问题,请参考以下文章

Matlab中整数规划问题

按下 UIButton 时,Swift 将文本保存到实例/全局变量

何时在 Swift 中使用全局变量

全局变量/常量如何在 swift 中变得懒惰

Swift 中全局变量和函数的最佳实践是啥?

Swift-Swift中的全局变量和函数的创建