Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UILabel和UIProgressView在我的通信类完成之前不会更新_Ios_Uilabel_Uiprogressview - Fatal编程技术网

Ios UILabel和UIProgressView在我的通信类完成之前不会更新

Ios UILabel和UIProgressView在我的通信类完成之前不会更新,ios,uilabel,uiprogressview,Ios,Uilabel,Uiprogressview,我有一个UILabel和一个UIProgressView,我正在对其进行多次更新,但在完成通信对象之前,不会呈现任何内容 我有一个ViewController: @interface UpdateServerViewController : UIViewController <TaskController> { AgentAssetManager * agentAssetManager; } @property (strong, nonatomic) IBOutlet UI

我有一个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
AgentAssetManager sendToServer is执行一系列步骤,并通过TaskController协议将通知发送回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 ....
不管有没有定时器,问题都是一样的。对于计时器,调试显示在调用agentAssetManager.updateNow之前安排了计时器,但是直到agentAssetManager.updateNow完成之后才调用updateTime方法。这甚至与updateNow中的sleep(5)配合使用,以避免线程争用情况

调试表明,所有UpdateServerViewController和AssetAgentManager似乎都在线程1中运行。除上述计时器外,我不执行任何NSRunLoop操作


我一定错过了一些基本的东西。任何帮助都将不胜感激

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

您可以尝试以下方法:

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

您使用什么进行实际的服务器通信?如果您正在使用任何带有contentsofURL方法的uuuuu,它们将阻止主线程,并且不会发生UI更新。我正在使用RestKit进行服务器通信。如果我按照您的建议使用dispatch_sync(),则整个线程将挂起/阻止。很奇怪。我开始认为RestKit(从AgentAssetManager运行)是在幕后做一些事情。
- (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];
}
- (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"];
}
dispatch_sync(dispatch_get_main_queue(), ^{
        [statusLabel setText:@"XXX Timer called"];
    }
);