如何从异步方法返回多个结果?

时间:2017-11-19 08:24:41

标签: ios asynchronous callback

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

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

示例类结构 - >类名

  1. 一个名为-(void)infoCallBack的方法,这是您必须调用以获得连续返回的方法。
  2. 内部-(void)infoCallBack - >有一个异步方法[self startRecording],它使用回调方法 void AudioInputCallback(..param..)使用AudioQueues异步录音。
  3. 最后在void AudioInputCallback(..param..)内 - >方法-(void) processAudio在那里,它持续处理数据并为我们提供整数
  4. 如何以这样的方式调用[ClassName infoCallBack]这样的方法,以便我们不断获得所有这些处理过的整数?

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

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

2 个答案:

答案 0 :(得分: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方法的完成块内,您可以使用结果整数来执行您想要的操作。

答案 1 :(得分:1)

  

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

从你写的其他内容中我怀疑你可以解决这个问题,你可能只需要休息一下。你已经找不到答案了......

  

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

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

  

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

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

typedef void (^SampleHandler)(int i);

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

@implementation ClassName
{
   SampleHandler mySampleHandler;
}

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

  

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

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

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

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

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

HTH