Ios 在使用dispatch_信号量后执行dispatch_

Ios 在使用dispatch_信号量后执行dispatch_,ios,objective-c-blocks,grand-central-dispatch,Ios,Objective C Blocks,Grand Central Dispatch,当我想在dispatch\u after块中执行代码时,我遇到了一个问题。 首先,当按下按钮以在屏幕上显示它时,我调用UIActivityIndicator,当UIActivityIndicator开始运行后,我想执行服务器调用,当收到服务器的响应时,我返回该值。 问题是:当我调用UIActivityIndicator运行并在之后调用服务器时,UIActivityIndicator即使在[UIActivityIndicatorInstance]启动时也不会显示在屏幕上,然后调用了服务器操作。 因

当我想在dispatch\u after块中执行代码时,我遇到了一个问题。
首先,当按下按钮以在屏幕上显示它时,我调用UIActivityIndicator,当UIActivityIndicator开始运行后,我想执行服务器调用,当收到服务器的响应时,我返回该值。

问题是:当我调用UIActivityIndicator运行并在之后调用服务器时,UIActivityIndicator即使在
[UIActivityIndicatorInstance]启动时也不会显示在屏幕上,然后调用了服务器操作。
因此,我决定在
之后使用
调度,以便在de
[UIActivityIndicationInstance startAnimating]之后等待一段时间当我这样做时,问题就变成了我必须返回值,因此,出于这个原因,请使用
dispatch\u信号量
来告诉我操作何时完成,然后返回值。
这里最大的问题是没有调用
之后的
调度。
这是我的代码,非常感谢您能帮助我解决这个问题或其他您想要的解决方案。
我想实现的主要思想是,我想在服务器操作执行时显示UIActivityIndicator,当它完成时,我想用相同的方法返回该值。


-(BOOL)getUserSatatus{
//此时UIActivityIndicator开始运行
[工具startActivityIndicator];
双延迟频率=0.5;
//这用于保存服务器响应。
__阻塞BOOL服务器响应;
dispatch\u semaphore\u t semaphore=dispatch\u semaphore\u create(0);
dispatch\u time\u t executionTime=dispatch\u time(立即分派时间,延迟时间*秒秒秒);
//我想在一段时间后执行服务器调用,以便在屏幕上显示第一个de指示器
dispatch_after(执行时间,dispatch_get_main_queue()^{
NSLog(@“这是服务器将调用的地方”);
//这是当我执行服务调用时,它返回一个
//分配给服务器响应。
serverResponse=[\u backendManager getStatus];
//这是信号量的信号,用于执行下一行。
调度信号灯(信号灯);
});
//等待信号,以便执行下一行。
调度信号灯等待(信号灯,调度时间永远);
return serverResponse;//下面是服务器返回响应。
}
你说:

这里的一个大问题是没有调用dispatch\u after

是的,这是因为您正在使用
dispatch\u semaphore\u wait
阻塞主线程,因此
dispatch\u after
永远没有机会在主线程上运行,您处于死锁状态

我们可以引导您找到解决此问题的方法,但您的代码中根本不应该有同步网络调用或信号量(原因有很多,不仅仅是为了活动指示器和解决死锁问题)

您应该删除这些同步网络请求,删除
之后的
dispatch\u,并删除信号量。如果您做到了所有这些,并遵循异步模式(比如使用完成块),那么活动指示器视图的内容将正常工作,并且也不会出现任何死锁

正确的答案是重构“后端管理器”以异步执行其请求(使用完成块),然后也使用带有
getUserStatus
方法的完成块模式

例如,假设您将
\u backendManager
getStatus
修复为异步行为:

- (void)getStatusWithCompletion:(void (^)(BOOL))completion {
    NSMutableURLRequest *request = ...   // build the request however appropriate
    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        BOOL status = ...;   // parse the response however appropriate
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completion) completion(status);
        });
    }];
    [task resume];
}
然后,您可以从您的问题中重构
getUserStatus
,以获得一个完成处理程序:

- (void)getUserStatusWithCompletion:(void (^)(BOOL))completion {
    // This is when the UIActivityIndicator is starts running
    [Tools startActivityIndicator];

    [_backendManager getStatusWithCompletion:^(BOOL status){
        [Tools stopActivityIndicator];
        if (completion) completion(status);
    }
}
然后需要获取用户状态的代码将执行以下操作:

[obj getUserStatusWithCompletion:^(BOOL success) {
    // use `success` here
}];

// but not here