在继续之前,等待方法完成执行

时间:2022-04-02 20:53:24

I am new to IOS development and am currently facing a problem.

我是IOS开发新手,目前正面临着一个问题。

When method A is called, it calls method B and then it wait for delegate connectionDidFinish which connectionDidFinish will execute MethodC.

调用方法A时,它调用方法B,然后等待connectionDidFinish, connectionfinish将执行MethodC。

My question is how do I ensure that methodA to methodC has finished executing before executing NSLog?

我的问题是如何确保methodA到methodC在执行NSLog之前已经完成?

I found that a way to solve this problem is to use notification center. Send notification to me after finishing executing methodC. I don't think this is a good solution. Is there another way to do this?

我发现解决这个问题的方法是使用通知中心。执行完methodC后发送通知给我。我认为这不是一个好的解决方案。还有别的办法吗?

Example:

例子:

 [a methodA];
 NSLog(@"FINISH");

2 个解决方案

#1


7  

If any of those methods perform actions asynchronously, you can't. You'll have to look into a different way of doing this. I personally try to use completion blocks when ever I can, although it's perfectly fine to do this other ways, like with delegate methods. Here's a basic example using a completion block.

如果这些方法中有任何一个异步执行操作,则不能。你将不得不另辟蹊径。我个人试着在我可以的时候使用完块,尽管用其他的方法,比如委托方法是完全可以的。下面是一个使用完成块的基本示例。

- (void)someMethod
{
    [self methodAWithCompletion:^(BOOL success) {
        // check if thing worked.
    }];
}

- (void)methodAWithCompletion:(void (^) (BOOL success))completion
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{

        // go do something asynchronous...

        dispatch_async(dispatch_get_main_queue(), ^{

            completion(ifThingWorked)

        });
    });
}

#2


2  

In the code you posted, methodA must finish executing before the log statement will execute.

在您发布的代码中,methodA必须在日志语句执行之前完成。

However, if methodA starts an asynchronous process that takes a while to finish and returns before it is finished, then you need to do something different. Usually you don't want to freeze the user interface while you are waiting, so you set up a delegate, pass in a completion block, or wait for an "ok, I'm done" notification.

然而,如果methodA启动一个需要一段时间完成并在完成之前返回的异步进程,那么您需要做一些不同的事情。通常,当您等待时,您不希望冻结用户界面,所以您设置了一个委托,通过一个完成块,或者等待一个“ok, I'm done”通知。

All those are very valid, good ways to solve the problem of waiting for asynchronous tasks to finish running.

所有这些都是非常有效的,可以很好地解决等待异步任务完成的问题。

Newer APIs are starting to use completion blocks. Examples are:

更新的api开始使用完成块。例子有:

  • presentViewController:animated:completion:, which takes a completion block that gets called once the new view controller is fully on-screen and "ready for business.
  • presentViewController:animated:completion:,它接受一个补全块,一旦新的视图控制器在屏幕上完全显示并“准备就绪”,这个补全块就会被调用。
  • animateWithDuration:animations:completion:, which takes a completion block that gets executed once the animation is finished, and
  • 动画:完成:,它取一个完成块,在动画完成后执行
  • sendAsynchronousRequest:queue:completionHandler:, which starts an asynchronous URL request (usually an HTTP GET or PUT request) and provides a completion block that gets called once the request has been completed (or fails)
  • sendAsynchronousRequest:queue:completionHandler:,它启动一个异步URL请求(通常是一个HTTP GET或PUT请求),并提供一个完成块,在请求完成(或失败)后被调用

#1


7  

If any of those methods perform actions asynchronously, you can't. You'll have to look into a different way of doing this. I personally try to use completion blocks when ever I can, although it's perfectly fine to do this other ways, like with delegate methods. Here's a basic example using a completion block.

如果这些方法中有任何一个异步执行操作,则不能。你将不得不另辟蹊径。我个人试着在我可以的时候使用完块,尽管用其他的方法,比如委托方法是完全可以的。下面是一个使用完成块的基本示例。

- (void)someMethod
{
    [self methodAWithCompletion:^(BOOL success) {
        // check if thing worked.
    }];
}

- (void)methodAWithCompletion:(void (^) (BOOL success))completion
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{

        // go do something asynchronous...

        dispatch_async(dispatch_get_main_queue(), ^{

            completion(ifThingWorked)

        });
    });
}

#2


2  

In the code you posted, methodA must finish executing before the log statement will execute.

在您发布的代码中,methodA必须在日志语句执行之前完成。

However, if methodA starts an asynchronous process that takes a while to finish and returns before it is finished, then you need to do something different. Usually you don't want to freeze the user interface while you are waiting, so you set up a delegate, pass in a completion block, or wait for an "ok, I'm done" notification.

然而,如果methodA启动一个需要一段时间完成并在完成之前返回的异步进程,那么您需要做一些不同的事情。通常,当您等待时,您不希望冻结用户界面,所以您设置了一个委托,通过一个完成块,或者等待一个“ok, I'm done”通知。

All those are very valid, good ways to solve the problem of waiting for asynchronous tasks to finish running.

所有这些都是非常有效的,可以很好地解决等待异步任务完成的问题。

Newer APIs are starting to use completion blocks. Examples are:

更新的api开始使用完成块。例子有:

  • presentViewController:animated:completion:, which takes a completion block that gets called once the new view controller is fully on-screen and "ready for business.
  • presentViewController:animated:completion:,它接受一个补全块,一旦新的视图控制器在屏幕上完全显示并“准备就绪”,这个补全块就会被调用。
  • animateWithDuration:animations:completion:, which takes a completion block that gets executed once the animation is finished, and
  • 动画:完成:,它取一个完成块,在动画完成后执行
  • sendAsynchronousRequest:queue:completionHandler:, which starts an asynchronous URL request (usually an HTTP GET or PUT request) and provides a completion block that gets called once the request has been completed (or fails)
  • sendAsynchronousRequest:queue:completionHandler:,它启动一个异步URL请求(通常是一个HTTP GET或PUT请求),并提供一个完成块,在请求完成(或失败)后被调用