我应该写啥完成处理程序?

Posted

技术标签:

【中文标题】我应该写啥完成处理程序?【英文标题】:What Completion Handlers Should I Write?我应该写什么完成处理程序? 【发布时间】:2018-05-25 13:56:15 【问题描述】:

刚刚了解了如何创建完成处理程序,我在原则上理解它们,但我不知道如何将这些想法付诸实践以完成我所需要的。

我有以下通用代码和故事板结构:sessionVC(一个 UIViewController)及其 UIView 拥有一个容器视图,其中包含一个嵌入到 animationVC(也是 UIViewController)及其 SKView 的 segue。

从 sessionVC 我想在 animationVC 的 SKView 中运行一系列动画。我希望尽快准备好每个动画(例如,在每个之前的动画仍在运行时),并且我希望每个动画在开始之前等待最后一个动画完成。请参阅下面的代码。

我的问题是,我应该在我的代码中放置什么来代替 ???s 来完成我想要的效果(上面提到,以及在代码 cmets 中的每个 *** 之后)?

// TO DELEGATE ANIMATION TO animationVC
protocol AnimateContentDelegate: AnyObject 

    prepareContent(_ Content, contentWasPrepared: ???)
    animateContent(animationDidComplete: ???)
    playAnimation()
    pauseAnimation()


// CONTROL THE OVERALL SESSION
class sessionVC: UIViewController 

    // INITIALIZE contentArray

    weak var delegate: AnimateContentDelegate?

    override func viewDidLoad 
        super.viewDidLoad()

        delegate = self.childViewControllers[0] as? AnimateContentDelegate

        runSession(contentArray)
    

    func runSession(_ contentArray) 

        for content in contentArray 

            delegate?.prepareContent(content, contentWasPrepared: ???)

            // ***DON’T START THE NEXT ANIMATION UNTIL contentWasPrepared
            //    DO CONTINUE THE CURRENT ANIMATION, AND ALLOW INTERACTIONS

            delegate?.animateContent(animationDidComplete: ???)

            // ***DON’T START THE NEXT ANIMATION UNTIL animationDidComplete
            //    DO CONTINUE THE CURRENT ANIMATION, AND ALLOW INTERACTIONS
       
    

    @IBAction func playOrPause(_ sender: UILongPressGestureRecognizer) 

         if sender == .possible || sender.state == .ended 

            delegate?.playAnimation()

         else if sender.state == .began 

            delegate?.pauseAnimation()
        
    


// PREPARE AND ANIMATE CURRENT CONTENT
class animationVC: UIViewController, AnimateContentDelegate 

    // SET UP SKVIEW

    func prepareContent(_ content: Content, prepCompleteHandler: ???) 
       // PREPARE THE CONTENT
       // ***REPORT WHEN IT IS FINISHED
    

    func animateContent(animationCompleteHandler: ???) 
        // ANIMATE THE CONTENT
        // ***REPORT IF IT RAN TO COMPLETION
   

    func playAnimation() 
        skView?.scene?.isPaused = false
    

    func pauseAnimation() 
        skView?.scene?.isPaused = true
    

【问题讨论】:

【参考方案1】:

按照通常的约定,您可以用稍微不同的措辞声明函数:

prepareContent(_ Content, completionHandler:  () -> Void )
animateContent(completionHandler:  () -> Void )

然后,在 SET UP SKVIEW 下方,您可以像这样调用委托函数:

delegate?.prepareContent(content, completionHandler: 
    self.delegate.animateContent(completionHandler: 
        // do whatever needs to be done upon completion
    )
)

(您也可以使用尾随闭包语法。) 通过像这样嵌套委托调用,您可以确保动画仅在准备完成后执行。

函数体如下所示:

func prepareContent(_ content: Content, completionHandler: (() -> Void)) 
    // ...
    completionHandler()


func animateContent(completionHandler: (() -> Void)) 
    // ...
    completionHandler()

如果您更喜欢使用可选的完成处理程序,i。 e.那些可以为零的,改变这样的功能:

func prepareContent(_ content: Content, completionHandler: (() -> Void)?) 
    // ...
    completionHandler?()

【讨论】:

感谢@Tom E 的指导。将 animateContent 函数嵌套在一个块中作为 prepareContent 的完成处理程序是最大的帮助,但是您对我的代码的其他修复使一切变得容易理解。 @Optimalist:很高兴我能帮上忙!【参考方案2】:

它应该看起来像:

func prepareContent(_ content: Content, completionHandler: @escaping (Bool, Any?) -> Void) -> Void 

   var finished : Bool = false
   var output : Any? = nil

   // prepare the content
   // possibly update the output

   //when ready : 
   finished = true
   completionHandler(finished, output)


那你就用它吧:

prepareContent(content: content, completionHandler:  (f, o) in 
   if f 
      if o != nil 
          //do something
      
      //else handle error
   
   //else handle error
)

您可以根据需要调整它,根据需要添加更多或更少的输出、错误日志等。

【讨论】:

动画方法或使用完成处理程序的任何方法也是如此【参考方案3】:

你想要这样的东西吗?

protocol AnimateContentDelegate: AnyObject 
    func prepareContent(content : Content, contentWasPrepared: ((Bool) -> Void)?)
    func animateContent(animationDidComplete: ((Bool) -> Void)?)
    func playAnimation()
    func pauseAnimation()


class YourObject : AnimateContentDelegate 

func prepareContent(content: Content, contentWasPrepared: ((Bool) -> Void)?) 
    // prepare content


func animateContent(animationDidComplete: ((Bool) -> Void)?) 
    // animate content


func playAnimation() 



func pauseAnimation() 


这样使用:

let yourObject = YourObject()
yourObject.animateContent(animationDidComplete:  finished in
    // animation did complete
)

【讨论】:

以上是关于我应该写啥完成处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在android中的方法参数中写啥[重复]

当 self 被释放时我应该调用完成处理程序吗

我应该在这里使用完成处理程序吗?如果是这样,如何最好地做到这一点?

我应该在 tableView(_:cellForRowAtIndexPath:) 方法中为自定义单元格写啥?

我正在从二级事件中心接收数据。我想将第二级数据转换为分钟级。我应该为此写啥查询?

c语言 #include<windows.h>是写啥的头文件?