gpt4 book ai didi

ios - 从异步回调更新 UI 的问题

转载 作者:行者123 更新时间:2023-11-28 21:33:54 33 4
gpt4 key购买 nike

我有以下代码:

@property (weak, nonatomic) IBOutlet UIView *loadingView;

-(void) hideLoadingScreen{
self.loadingViewRect = self.loadingView.frame;
[self.loadingView setHidden:YES];
[self.loadingView setFrame:CGRectMake(0,0,0,0)];
}
- (void)viewDidAppear:(BOOL)animated{
[self.apiClient checkLoggedInWithCallback:^(int status){
if(status == ONLINE_LOGGED_IN){
[self.dbAPI isPullSynchronized:^(BOOL isPullSynced){
if(isPullSynced){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
[self hideLoadingScreen];
} else {
[self.apiClient getTodayVisits:^(NSArray* visits){
[self.dbAPI insertTodayVisits:visits withCallback:^(int status){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}];
}];
}
}];
} else if(status == ONLINE_NOT_LOGGED_IN || status == ONLINE_INVALID_TOKEN || status == OFFLINE_NOT_LOGGED_IN) {
//Redirect to login
} else {
//Get from Local DB
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}
}];
}

hideLoadingScreen 方法不会执行(我的意思是它会执行,但 UI 不会更新)。

我尝试了所有方法使其工作(包括通过 GCD 和 performSelectorOnMainThread 将 [self hideLoadingScreen] 分派(dispatch)到主线程/制作一个 __block BOOL 变量 isLoading 并在主线程上休眠直到该变量被更改等)。我还在 viewDidAppear 方法上调用了 hideLoadingView 方法并且它有效,但我希望它在执行回调时隐藏。不幸的是,我无法通过在 stackoverflow 上搜索找到解决方案,也没有在 google 上搜索(我必须说我尝试了我找到的所有解决方案)。

L.E.我按照 Rob Napier 的建议记录了 self.loadingView

新代码:

-(void) hideLoadingScreen{
self.loadingViewRect = self.loadingView.frame;
NSLog(@"hideLoadingScreen before: %@",self.loadingView);
[self.loadingView setHidden:YES];
[self.loadingView setFrame:CGRectMake(0,0,0,0)];
NSLog(@"hideLoadingScreen after: %@",self.loadingView);
}

- (void)viewDidAppear:(BOOL)animated{
NSLog(@"%@",self.loadingView);
[self.apiClient checkLoggedInWithCallback:^(int status){
if(status == ONLINE_LOGGED_IN){
[self.dbAPI isPullSynchronized:^(BOOL isPullSynced){
if(isPullSynced){
dispatch_async(dispatch_get_main_queue(), ^{
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
NSLog(@"async before: %@",self.loadingView);
[self hideLoadingScreen];
NSLog(@"async after: %@",self.loadingView);
});
} else {
[self.apiClient getTodayVisits:^(NSArray* visits){
[self.dbAPI insertTodayVisits:visits withCallback:^(int status){
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}];
}];
}
}];
} else if(status == ONLINE_NOT_LOGGED_IN || status == ONLINE_INVALID_TOKEN || status == OFFLINE_NOT_LOGGED_IN) {
//Redirect to login
} else {
//Get from Local DB
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
}
}];
}

日志:

2016-01-08 16:22:25.973 sunwaves.reporting[4566:282042] async before: <UIView: 0x7fa681e745d0; frame = (0 0; 1024 650); autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.973 sunwaves.reporting[4566:282042] hideLoadingScreen before: <UIView: 0x7fa681e745d0; frame = (0 0; 1024 650); autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.974 sunwaves.reporting[4566:282042] hideLoadingScreen after: <UIView: 0x7fa681e745d0; frame = (0 0; 0 0); hidden = YES; autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>
2016-01-08 16:22:25.974 sunwaves.reporting[4566:282042] async after: <UIView: 0x7fa681e745d0; frame = (0 0; 0 0); hidden = YES; autoresize = RM+H+BM; layer = <CALayer: 0x7fa681e291c0>>

最佳答案

大多数 UIKit 调用必须在主队列上进行。您应该使用 dispatch_async(dispatch_get_main_queue(),... 来执行此操作。

这至少包括您对 reloadData 的调用。

您对 self.data 的赋值也可能不是线程安全的(除非您在 setter 中做了一些特殊的事情)。所以那些需要在主队列中。

当然还有您对 hideLoadingScreen 的调用。

我假设这些 block 中的大多数都在主队列之外执行,所以这意味着在几个地方放置 dispatch_async

- (void)viewDidAppear:(BOOL)animated{
[self.apiClient checkLoggedInWithCallback:^(int status){
if(status == ONLINE_LOGGED_IN){
[self.dbAPI isPullSynchronized:^(BOOL isPullSynced){
if(isPullSynced){
dispatch_async(dispatch_get_main_queue(), ^{
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
[self hideLoadingScreen];
});
} else {
[self.apiClient getTodayVisits:^(NSArray* visits){
[self.dbAPI insertTodayVisits:visits withCallback:^(int status){
dispatch_async(dispatch_get_main_queue(), ^{
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
});
}];
}];
}
}];
} else if(status == ONLINE_NOT_LOGGED_IN || status == ONLINE_INVALID_TOKEN || status == OFFLINE_NOT_LOGGED_IN) {
//Redirect to login
} else {
//Get from Local DB
dispatch_async(dispatch_get_main_queue(), ^{
self.data = [self.dbAPI getTodayVisits];
[[self tableView] reloadData];
});
}
}];
}

关于ios - 从异步回调更新 UI 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34678547/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com