我的问题的高级摘要:
我有一个 UITableViewController (TVC1),它执行 performSegue 来调用静态 UITableViewController (TVC2),以便用户可以输入详细信息。在 TVC2 上按下一个名为“添加另一个”的按钮后,我希望 TVC2 保存其数据并再次调用以添加另一条记录。
细节:
我有一个实现此数据模型的 tableViewController (TVC1):
- Category <=> maps to tableview sections
- Group <=> maps to tableview rows
- Detail <=> maps to tableview rows
显示可能如下所示:
- Section 0: Category 1
- Row 0: Group A
- Row 1: Detail x1
- Row 2: Detail y2
- Row 3: Detail z3
- Row 4: Group B
- Row 5: Detail x2
- Row 6: Detail y2
- Row 7: Detail y3
例如,当我想通过单击详细信息行 5 来编辑详细信息时,我performSegue
在didSelectRowAt
.
在TVC1.prepareForSegue
我提供 TVC1 作为 TVC2 的代表,可以添加/编辑该细节。我还将要编辑的细节数据提供给 TVC2 的属性。
在 TVC2 上 - 提供详细信息后 - 用户可以单击工具栏中的保存按钮,这将保存数据并将他带回 TVC1。或者,在可以输入详细信息的表格末尾,我有一个按钮:
- 添加另一个细节
这个想法是用户被直接带到一个新屏幕,他们可以在其中为同一组添加另一个详细信息。所以基本上在 TVC2 消失后,它应该会再次出现以添加新的细节。
在 TVC2 中,我将此按钮链接到unwindFrom
TVC1 上的方法。然后在prepareForSegue
TVC2 中,我调用委托 (TVC1) 上的协议方法以返回编辑的详细信息,并提供一个调用结构NextAction
来通知根 TVC1 它的下一步应该是什么。在这种情况下,它应该在同一组中添加另一个细节。
然后在unwindFrom
TVC1 的方法中,我查看nextAction
并启动下一个performSegue
.
我不知道其他地方可以做到这一点。对我来说,这是我可以展示下一个动作的最后一个钩子,再次是 TVC2。
这会导致奇怪的行为。它似乎工作一次,但不是第二次。
调试显示(=====> 行是我自己的打印调试行):
========> TVC2 prepare start (means the add more details button was pressed)
========> TVC1 newDetailValues begin (TVC2 calling the delegate protocol method to provide back edited data - including NextAction)
========> TVC1 newDetailValues end
========> TVC2 prepare end (I am not sure if TVC2 is now closed/inaccessible)
========> TVC1 unwindFromAddEdit begin (here nextAction is evaluated and a performSegue done)
========> TVC1 prepare begin (initiated by the performSegue)
========> TVC1 prepare end
'Presenting view controllers on detached view controllers is discouraged <Project.TVC1: 0x.........>.'
========> TVC1 unwindFromAddEdit end
注意错误/警告:
'Presenting view controllers on detached view controllers is discouraged <Project.TVC1: 0x.........>.'
但我确实看到了 TVC2 的细节。但是当我再次单击该按钮时,它会显示根 TVC1 而不是 TVC2。xcode 现在说:
'Warning: Attempt to present <UINavigationController: 0x.........> on <Project.TVC1: 0x.........> whose view is not in the window hierarchy!'
我觉得这与线程有关——可能在TVC1.unwindFrom
TVC2 的范围内运行。
当我编辑TVC1.unwindFrom
和替换时:
performSegue(withIdentifier: "AddDetails", sender: self)
... 和:
DispatchQueue.main.async {
performSegue(withIdentifier: "AddDetails", sender: self)
}
一切正常。
但:
- 我不明白发生了什么。
- 我无法评估我正在做的事情是否是线程安全的。例如:我是否在 TVC2 关闭和 TVC1 同时调用 TVC2 之间引入了竞争条件?
谁能照亮正在发生的事情?