gpt4 book ai didi

ios - UILabel 和 UIProgressView 直到我的通信类完成才更新

转载 作者:行者123 更新时间:2023-11-28 17:37:29 25 4
gpt4 key购买 nike

我有一个 UILabel 和 UIProgressView,我要对其进行多次更新,但在我的通信对象完成之前不会呈现任何内容。

我有这个 ViewController:

@interface UpdateServerViewController : UIViewController <TaskController> {
AgentAssetManager * agentAssetManager;
}

@property (strong, nonatomic) IBOutlet UIButton * updateNowButton;
@property (strong, nonatomic) IBOutlet UILabel * statusLabel;
@property (strong, nonatomic) IBOutlet UILabel * lastUpdateSuccessTimeLabel;
@property (strong, nonatomic) IBOutlet UILabel * lastUpdateAttemptTimeLabel;
@property (strong, nonatomic) IBOutlet UILabel * lastUpdateResultLabel;
@property (strong, nonatomic) IBOutlet UIProgressView * progressView;

- (IBAction) updateNow:(id) sender;
- (void) updateLabels;
- (void) scheduleInNextRunloopSelector:(SEL)selector;
- (void) taskSetStatus:(NSString *)status;
- (void) taskFinishedSuccessfully;
- (void) taskFinishedUnSuccessfully;

@end

updateNow 方法调用 AgentAssetManager:

[self scheduleInNextRunloopSelector:@selector(updateTime:)];

McDbg(m, d+1, @"Calling AgentAssetManager sendToServer");
// [statusLabel setText:@"Contacting Server"];
[agentAssetManager sendToServer:true taskController:self];

AgentAssetManager sendToServer 执行一系列步骤并通过 TaskController 协议(protocol)将通知发送回 UpdateServerViewController:

- (void) sendToServer:(Boolean) notifyUser 
taskController:(id<TaskController>) taskCtlr
{
char * m = "AgentAssetManager.sendToServer";
int d = 0;
int steps = 6; // Total number of steps

McDbg(m, d, @"Send Asset data to server");
McDbg(m, d+1, @"Notify User about status/errors=%s",
(notifyUser) ? "YES" : "NO");

if (taskCtlr != nil) {
[taskCtlr taskSetProgress:(float)1/(float)steps];
[taskCtlr taskSetStatus:@"Checking if server is reachable"];
}

McDbg(m, d+1, @"SLEEPING");
sleep(5); // XXX tmp debug

ServerStatusManager *statusMgr = [[ServerStatusManager alloc] init];
Boolean ready = [statusMgr isServerReady];
McDbg(m, d+1, @"Server Status ready=%s", (ready) ? "YES" : "NO");
if (!ready) {
NSString *msg = @"Server could not be reached";
McLogWarn(m, @"Server Not ready %@", [statusMgr serverUrlBase]);
[self updateResult:false];
if (notifyUser)
[McUiError showMessage:msg];
if (taskCtlr) {
[taskCtlr taskSetStatus:msg];
[taskCtlr taskFinishedUnSuccessfully];
}
return;
}

McDbg(m, d+1, @"Getting Asset data");
if (taskCtlr != nil) {
[taskCtlr taskSetProgress:(float)2/(float)steps];
[taskCtlr taskSetStatus:@"Gathering data"];
}

... etc ....

这里是 UpdateServerViewController taskSetProgress 和 taskSetStatus:

- (void) taskSetStatus:(NSString *) status
{
char * m = "UpdateServerViewController.taskSetStatus";
int d = 0;

McDbg(m, d, @"Status=<%@>", status);
[statusLabel setText:status];
McDbg(m, d+1, @"Finished");
}

- (void) taskSetProgress:(float) percent
{
[progressView setHidden:false];
[progressView setProgress:percent animated:YES];
}

调试输出清楚地表明 UpdateServerViewController taskSetProgress 和 taskSetStatus 在预期的时候被调用。问题是新的设置值在整个 agentAssetManager.updateNow 方法完成之前不会生效。

基于在此站点上搜索类似的 UILabel 问题,我添加了一个计时器方法:

- (void) scheduleInNextRunloopSelector:(SEL)selector 
{
char * m = "UpdateServerViewController.scheduleInNext";
int d = 0;

McDbg(m, d, @"Starting");
NSDate *fireDate = [[NSDate alloc] initWithTimeIntervalSinceNow:0.5]; // 500 ms
NSTimer *timer = [[NSTimer alloc]
initWithFireDate:fireDate interval:0.5 target:self
selector:selector userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

}

- (void)updateTime:(NSTimer *)timer
{
char * m = "UpdateServerViewController.updateTime";
int d = 0;

McDbg(m, d, @"Starting");
[statusLabel setText:@"XXX Timer called"];
}

不管有没有定时器,问题都是一样的。使用计时器,调试显示计时器安排在调用 agentAssetManager.updateNow 之前,但是在 agentAssetManager.updateNow 完成之前不会调用 updateTime 方法。这甚至在 updateNow 中使用 sleep(5) 来尝试避免线程竞争条件。

调试显示所有 UpdateServerViewController 和 AssetAgentManager 似乎都在线程 1 中运行。除了上述计时器外,我没有执行任何 NSRunLoop。

我一定是漏掉了一些基本的东西。非常感谢任何帮助!

最佳答案

确保在主线程中进行任何 ui 更改。

你可以尝试这样的事情:

dispatch_sync(dispatch_get_main_queue(), ^{
[statusLabel setText:@"XXX Timer called"];
}
);

关于ios - UILabel 和 UIProgressView 直到我的通信类完成才更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9437892/

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