Ios 在使用dispatch_信号量后执行dispatch_
当我想在dispatch\u after块中执行代码时,我遇到了一个问题。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]启动时也不会显示在屏幕上,然后调用了服务器操作。 因
首先,当按下按钮以在屏幕上显示它时,我调用UIActivityIndicator,当UIActivityIndicator开始运行后,我想执行服务器调用,当收到服务器的响应时,我返回该值。
问题是:当我调用UIActivityIndicator运行并在之后调用服务器时,UIActivityIndicator即使在
[UIActivityIndicatorInstance]启动时也不会显示在屏幕上调用了code>,然后调用了服务器操作。
因此,我决定在
之后使用调度,以便在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