Ios 解卷时的线程问题

Ios 解卷时的线程问题,ios,xcode,multithreading,thread-safety,uipresentingcontroller,Ios,Xcode,Multithreading,Thread Safety,Uipresentingcontroller,我的问题的高级别摘要: 我有一个UITableViewController(TVC1),它执行性能检查来调用静态UITableViewController(TVC2),以便用户可以输入详细信息。在按下TVC2上名为“添加另一条”的按钮后,我希望TVC2保存其数据并再次被调用以添加另一条记录 详情: 我有一个tableViewController(TVC1),它实现了这个数据模型: - Category <=> maps to tableview sections - Group

我的问题的高级别摘要:

我有一个UITableViewController(TVC1),它执行性能检查来调用静态UITableViewController(TVC2),以便用户可以输入详细信息。在按下TVC2上名为“添加另一条”的按钮后,我希望TVC2保存其数据并再次被调用以添加另一条记录

详情:

我有一个tableViewController(TVC1),它实现了这个数据模型:

- Category <=> maps to tableview sections
  - Group <=> maps to tableview rows
    - Detail <=> maps to tableview rows
例如,当我想通过单击详细信息行5来编辑详细信息时,我会在
didSelectRowAt
中执行
performSegue

TVC1.prepareforsgue
中,我提供TVC1作为TVC2的代表,可在其中添加/编辑该细节。我还提供了要编辑的TVC2属性细节数据

在TVC2上-提供详细信息后-用户可以单击工具栏中的保存按钮,保存数据并返回TVC1。或者,在可以输入详细信息的表单末尾,我有一个按钮:

  • 添加另一个细节
这个想法是用户直接被带到一个新的屏幕,在那里他们可以为同一组添加另一个细节。所以基本上在TVC2消失后,它应该再次出现以添加新的细节

在TVC2中,我将此按钮链接到TVC1上的
unwindFrom
方法。然后在TVC2的
prepareforsgue
中,我调用委托(TVC1)上的协议方法,以返回编辑的详细信息,并提供一个名为
NextAction
的结构,以通知根TVC1其下一个操作应该是什么。在这种情况下,应在同一组中添加另一个详细信息

然后在TVC1的
unwindFrom
方法中,我查看
nextAction
并启动下一个
performsgue

我不知道还有什么地方可以这样做。对我来说,这是最后一个钩子,我可以提出下一个行动,这是TVC2再次

这导致了奇怪的行为。它似乎只工作了一次,但不是第二次

调试显示(==>行是我自己的打印调试行):

。。。与:

DispatchQueue.main.async {
   performSegue(withIdentifier: "AddDetails", sender: self)
}
一切正常

但是:

  • 我不明白发生了什么事
  • 我无法评估我所做的是否是线程安全的。例如:我是否在TVC2关闭和TVC1同时调用TVC2之间引入竞争条件

  • 谁能对正在发生的事情有所了解?

    答案由Paulw11在评论中提供:

    最好的方法是在每次调用TVC2后按下“添加另一个”按钮时不要松开

    相反,“添加另一个”按钮应该被控制拖动到同一个导航控制器,并以模式进行演示

    在prepareForSegue中,TVC2需要的详细信息可以从当前ViewController复制到其自身的新实例

    在某个时刻,用户使用工具栏中的“取消”或“保存”按钮,将所有内容都展开到TVC1


    这样做还可以使UI看起来更干净,因为对TVC1的展开不可见

    那样的话,我不会放松的。我会推动TVC2的另一个实例来添加新项,然后当您在该实例中点击save时,将其放回到TVC1,这不是线程问题。您正在视图不在窗口(视图层次结构)中的视图控制器(Project.TVC1)上显示视图控制器(NavigationController)。这意味着TVC1即将被删除或甚至被删除。@Paulw11:你的意思是:TVC1通过performSegue调用TVC2,用户单击TVC2上的“保存并添加另一个”按钮后,我执行一个从TVC2上的按钮到其自己控制器TVC2的序列?当用户在第二个TVC2实例中工作时,这会使前一个TVC2对象保持活动状态吗?在这种情况下,我不应该建立一个TVC2的堆栈吗?@DamianRzeszot:对于TVC1上的编辑细节序列,我直接做一个TVC2的节目序列。对于添加细节,我对TVC2的导航控制器进行了模态分析。因此,事件的顺序是:TVC1=>Show Segue of TVC2=>unwind to TVC1=>in unwind:Present Modally Segue NavContr of TVC2=>unwind to TVC1=>in unwind:Present Modally Segue NavContr TVC2等。是的,您将有一堆TVC2,但当您将它们放回TVC1时,它们将被释放。这就是一段放松的旅程的美妙之处;它可以轻松地展开任意数量的视图控制器,以返回到您想要的位置。
    ========> 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.........>.'
    
    'Warning: Attempt to present <UINavigationController: 0x.........> on <Project.TVC1: 0x.........> whose view is not in the window hierarchy!'
    
    performSegue(withIdentifier: "AddDetails", sender: self)
    
    DispatchQueue.main.async {
       performSegue(withIdentifier: "AddDetails", sender: self)
    }