ios 5.1中的autorefreshing uiviewcontroller

时间:2013-12-04 14:53:52

标签: ios objective-c uiviewcontroller nsthread

我有UIViewController显示在我的Iphone应用上完成的计算的进度状态,以查看在同一UIViewController上按下刷新按钮所需的进度百分比,如何在不需要手动按下按钮的情况下自动完成

这是我的代码:

- (void)viewDidLoad{
    [NSThread detachNewThreadSelector:@selector(autoRefresh) toTarget:self withObject:nil];
    ...
}

然后:

- (void) autoRefresh{
    while (1) {
        sleep(2);
        sendFromButton = false;
        if (flag == 1) { // which button pushed last
            [self CaptureButton:self];
        }
        if (flag == 2) { // which button pushed last
            [self ExampleButtonfun:self];
        }
        if (flag == 3) { // which button pushed last
            [self CommuintyButton:self];
        }
    } 
}

当第一次查看控制器时,viewDidLoad被调用,创建一个线程来运行自动刷新功能,但是虽然我以正确的方式做到了,但我没有刷新控制器!,请帮忙我的。

1 个答案:

答案 0 :(得分:0)

如果要进行一系列计算并显示进度,则必须在后台线程中进行计算,然后更新主线程上的UI。如果您在主线程中进行了计算,那么您的UI将永远无法自行更新。

但是,假设您已成功在后台线程上启动了耗时的计算,则可以使用计时器(或显示链接)更新进度条,例如,定义计时器属性:

@property (nonatomic, weak) NSTimer *timer;

然后从主队列安排重复计时器并开始后台进程:

// start the timer

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 
                                                  target:self
                                                selector:@selector(updateProgress:) 
                                                userInfo:nil
                                                 repeats:YES];
self.timer = timer;

// use whatever mechanism you want for initiating your background process (though dispatch queues and operation queues may be easier than dealing with threads directly)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self startTimeConsumingProcess]
});

然后,您显然会实施更新UI的updateProgress:方法:

- (void)updateProgress:(NSTimer *)timer
{
    // update the UI progress bar here
}

当计算完成或视图被解除时,不要忘记invalidate该计时器,因为如果不这样做,计时器将保持对视图控制器的强引用,你将拥有一个强大的参考周期(又称保留周期)。


顺便说一下,另一种逻辑方法,而不是使用计时器,只是让后台计算调度UI更新,将进度条更新回主队列,例如

- (void) startSomeTimeConsumingProcess
{
    // start time consuming process in background queue

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        BOOL finished = NO;

        while (!finished)
        {
            // do something, updating `finished` when done

            // update UI to report the progress in the main queue, though:

            dispatch_async(dispatch_get_main_queue(), ^{
                // update progress UI here
            });
        }
    });
}

此方法的唯一考虑因素是此后台进程在进度条更新时调度主队列的速度有多快。如果更新太快,您可以使用进度更新来备份主队列。因此,上面基于计时器(或显示链接)的方法的吸引力。但如果你确信这些更新会发生得足够慢,那么这种替代方法可能会更容易。