【问题标题】:iOS: Waiting for API Completion Block and returning the resultiOS:等待 API 完成块并返回结果
【发布时间】:2014-05-07 01:46:08
【问题描述】:

使用继承。

我有一个子类调用父类中运行调用服务器 API 的方法。

-(IBAction)buttonPressed
{
    [self methodInParentClassThatCallsTheAPI:param];
    // This is where I would like the call back
     if (success from the server API) // do something with the UI
     else if (failure from the server API) // do so something else with the UI
}

父类:

- (void)methodInParentClassThatCallsTheAPI:(NSString *)param
{
      //The method below calls the server API and waits for a response.  
      [someServerOperation setCompletionBlockWithSuccess:^(param, param){
        // Return a success flag to the Child class that called this method
      } failure:^(param, NSError *error){
        // Return a failure flag to the Child class that called this method
      }
}

如何使用块来完成此操作?除了块之外还有更好的方法吗?请提供代码示例

【问题讨论】:

    标签: objective-c ios7 objective-c-blocks


    【解决方案1】:

    在methodInParentClass 上创建一个完成块,如下所示:

    - (void)methodInParentClassThatCallsTheAPI:(NSString *)param completionBlock:(void (^)(BOOL success))completionBlock;
    

    然后使用适当的值在块成功/失败中触发它,如下所示:

    completionBlock(YES);
    

    编辑:顺便说一句,请注意返回可能不在主线程上,因此如果您打算进行 UI 更新,您可以使用 dispatch_async(dispatch_get_main_queue, ^{}); 触发返回块;

    EDIT2:既然你似乎暗示这是一个按钮点击的结果,如果你的孩子是一个等待返回的 VC,请记住这个块将返回异步(显然因为这是它的设计目的)所以如果你需要无论出于何种原因保持用户,您都需要让主线程显示某种加载指示器并保持用户输入事件。请记住,如果您不这样做,则 UI 将在完成块触发之前继续响应,因此至少您将要禁用该按钮,以便用户无法多次按下它,然后您可以在完成时重新启用它阻止来自子 VC 的触发。

    EDIT3:好的,这是调用代码。

    -(IBAction)buttonPressed
    {
        [self methodInParentClassThatCallsTheAPI:param withCompletionBlock:^(BOOL success){
            if (success) {
              // do something with the UI
            } else {
                // Do something else
            }
        }];
    }
    

    【讨论】:

    • 我该如何调用这个方法?谢谢。
    • 就像您使用任何阻止方法一样。您正在使用上面的 someServerOperation 方法这样做,这完全一样。
    • 在您的子 VC 中看到那些更新 UI 的 if/else 语句了吗?他们将进入该完成块并在方法返回时被触发,但请参阅我上面的编辑,以便您了解行为并确保您在主线程上进行任何 UI 更新。
    • 为了清楚起见:您将一个块从 VC 传递到父控制器并说“完成后运行此块中的代码”。您还可以将一个局部变量设置为操作的结果,这也是完成块中 BOOL 成功的原因。试试吧,它会做你想做的。
    • 另一件事:如果您将 nil 传递给完成块,如果您尝试调用 completionBlock(YES) 或 completionBlock(NO),它将使您的代码崩溃。为了安全起见,最好在完成块这样说: if(completionBlock) ... 在你触发它之前,因为一些调用者可能不关心完成块。
    猜你喜欢
    • 1970-01-01
    • 2020-05-13
    • 2012-08-19
    • 2023-03-17
    • 2013-01-08
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多