当我想在dispatch_after块中执行代码时,我遇到了问题
首先,当按下按钮以便在屏幕上显示它并且在uiactivityindicator开始运行之后我调用UIActivityIndicator时我想执行服务器调用,当我从服务器得到响应时我返回该值。
问题是:当我调用我的UIAtivityIndicator运行并在之后进行服务器调用时,即使调用[UIActivityIndicatorInstance startAnimating];
,UIActivityIndicator也不会显示在屏幕上,之后调用服务器操作。登记/>
因此我决定使用dispatch_after
以便在de [UIActivityIndicatorInstance startAnimating];
之后等待一段时间。当我执行此操作时,问题变为我必须返回值时,因此使用{ {1}}告诉我操作何时完成然后返回值。
这里的一个大问题是dispatch_semaphore
没有被调用。
这是我的代码,我感谢您可以帮助我解决这个问题或者您想到的其他解决方案
我想要完成的主要想法是我想在服务器操作执行时显示UIActivityIndicator,当它完成时我想以同样的方法返回该值。
< / p>
dispatch_after
答案 0 :(得分:2)
你说:
这里的一个大问题是没有调用dispatch_after。
是的,那是因为你用dispatch_semaphore_wait
来阻止主线程,所以dispatch_after
永远不会有机会在主线程上运行而你会陷入僵局。
我们可以引导您解决此问题,但您根本不应该在代码中使用同步网络调用或信号量(出于多种原因,不仅仅是因为您的活动指示器和解决您的死锁问题)。
您应删除这些同步网络请求,删除dispatch_after
,然后删除信号量。如果你做了所有这些,而是遵循异步模式(比如使用完成块),那么你的活动指标视图内容将正常工作,你也不会有任何死锁。
正确的答案是重构“后端管理器”以异步方式执行其请求(使用完成块),然后使用完成块模式和getUserStatus
方法。
例如,假设您修复了getStatus
的{{1}}以异步行为:
_backendManager
然后你可以从你的问题中重构- (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);
}
}