【问题标题】:How to return multiple results from Asynchronous method?如何从异步方法返回多个结果?
【发布时间】:2017-11-19 08:24:40
【问题描述】:

注意:这个问题与使用的语言没有任何关系,即 Swift/Objective-C

我似乎无法理解如何解决这样的问题。 连续处理数据的异步方法如何将这些处理后的值返回给函数?

示例类结构 -> ClassName

  1. 一个名为-(void)infoCallBack的方法,这是您必须调用的方法才能连续获得回报。
  2. -(void)infoCallBack 内部-> 有一个异步方法[self startRecording],它通过回调方法 void AudioInputCallback(..param..) 使用AudioQueues 异步录制音频。
  3. 终于在 void AudioInputCallback(..param..) 内部 -> 一个方法 -(void) processAudio 在那里,它不断处理数据并给我们一个整数

如何调用像[ClassName infoCallBack] 这样的方法,以便我们不断地获取所有这些处理过的整数?


编辑:我搜索了 SO,并遇到了 完成处理程序块:虽然完成处理程序只在调用 completionHandler() 后返回一次值。此外,该方法的另一个问题是如何将这个completionHandler 传递给className 结构中的多个方法,如图所示。

我遇到了委托,它说当不断返回不同的值并且某些状态发生变化时,我们应该调用委托。但是在我从 ClassName 调用函数 infoCallBack 后,我被困在如何返回值上,即 [ClassName infoCallBack],它可以不断地为调用此函数的人提供正在处理的值。

【问题讨论】:

    标签: ios asynchronous callback


    【解决方案1】:

    其实我并没有完全理解你的问题,但我会在我的理解中给你答案

    在我看来,你可以使用块来处理进程更新。

    typedef void (^ProcessHandlerBlock) (NSInteger i);
    
    - (void)infoCallBackWithProcessHandlerBlock:(ProcessHandlerBlock)block {
      [self startRecordingWithProcessHandlerBlock:(ProcessHandlerBlock)block];
    }
    
    - (void)startRecordingWithProcessHandlerBlock:(ProcessHandlerBlock)block {
      [self audioInputCallbackWithParam1:@"1" param2:@"2" processHandlerBlock:(ProcessHandlerBlock)block];
    }
    
    - (void)audioInputCallbackWithParam1:(id)param1 param2:(id)param2 processHandlerBlock:(ProcessHandlerBlock)block {
      [self processAudioWithProcessHandlerBlock:(ProcessHandlerBlock)block];
    }
    
    - (void)processAudioWithProcessHandlerBlock:(ProcessHandlerBlock)block {
      // Assume this is your process method callback
      [NSTimer scheduledTimerWithTimeInterval:1.f repeats:YES block:^(NSTimer * _Nonnull timer) {
        // After receive integer, pass it to block.
        block(1);
      }];
    }
    

    当您想使用它们时,请致电

    [self infoCallBackWithProcessHandlerBlock:^(NSInteger i) {
      NSLog(@"%l", i); // Do whatever you want here
    }];
    

    infoCallBackWithProcessHandlerBlock方法的完成块内,你可以使用结果整数来做你想做的事情。

    【讨论】:

    • 我赞成你的回答,虽然它没有给出完整的见解,但谢谢你。我会以更好的方式解释。我的异步函数进行记录并继续处理记录并不断计算值。一旦它计算出一个值,我希望它返回这个值。现在,它不能用完成处理程序来完成,因为它只是不计算一个值并返回它并停在那里。它不断计算并返回许多值。
    • @ShivanshJagga 我已经更新了我的答案,你可以再次查看
    • 您好,我稍后会给出正确答案。我终于用委托得到了它。不过,如果有completionHandler解决方案,我还是会期待的。几个小时后我会发布并编辑我的问题。
    • @ShivanshJagga 你应该检查一下。我试过了,block 每秒都打电话。我非常渴望看到delegate 的答案;)
    【解决方案2】:

    我似乎无法理解如何解决这样的问题。

    根据您所写的其余内容,我怀疑您可以理解这一点,您可能只需要休息一下。你已经在不知不觉中找到了答案……

    我已经搜索过 SO,并且遇到了完成处理程序块:虽然完成处理程序只在调用 completionHandler() 后返回一个值。

    短语“完成处理程序块”可以写成“用作完成处理程序的块” - 块只是一个块,您可以根据需要多次调用它,将其存储在变量中,等等。 completion handler 通常只被调用一次,例如,result Reporter 可能会被调用多次。

    此外,这个方法的另一个问题是如何将这个completionHandler传递给className结构中的多个方法,如图所示。

    块是一种对象,与其他对象一样,您的类 instance 可能需要在许多方法中使用它不需要传递,但可以存储在 instance 中变量。为了便于使用,首先声明块类型的简写,比如:

    typedef void (^SampleHandler)(int i);
    

    然后声明一个合适的实例变量:

    @implementation ClassName
    {
       SampleHandler mySampleHandler;
    }
    

    现在像任何其他实例变量一样使用它 - 初始化它 (mySampleHandler = ...;), use it to call the block (mySampleHandler(42);`)

    我遇到了委托,它说当不断返回不同的值并且某些状态发生变化时,我们应该调用委托。但我被困在如何......

    块和委托通常用于类似的目的,您可以使用它们以基本相同的方式解决您的问题 - 将块/委托引用存储在实例变量中,调用块/委托方法以返回一个值。您只需要决定哪个最适合您的用例:

    • 是一个函数。块通常在调用站点内联创建,并且可以在创建它的环境中引用(有时修改)变量。像任何函数一样,它(通常)是一个单一操作的东西 - 传递参数,产生副作用/返回结果。

      • 委托是一个对象。像任何其他对象一样,它需要一个接口/实现。像任何对象一样,它可以有多个方法,所以它是一个多操作的东西。

    在你的情况下 - 返回一个值 - 一个块可能是最好的选择,但你需要决定。

    HTH

    【讨论】:

    • 我希望我能多次投票给你。你说得对,我需要休息。我确实得到了正确的答案,我很快就会发布。 :) 另外,如果您能对此提供帮助,我将不胜感激,人们赞成,所以我猜这是一个好问题:stackoverflow.com/questions/47278081/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-02-22
    • 1970-01-01
    • 2018-09-01
    • 2012-02-14
    相关资源
    最近更新 更多