2012-05-02 48 views
0

我试图更新“而循环”内的UILabel但不改变UILabel文本。我知道在主线程的当前运行循环结束时会像往常一样显示iOS。但是,如何才能解决这个问题(在ftp.AsyncFinished功能是由外部奇尔卡特FTP模块提供):更新的UILabel在“while循环”

的数据每秒更新一次。我搜索了这个论坛和Apple的文档,但我无法弄清楚在主线程的“while循环”中更新UILabel的正确方法。我可以使用什么而不是一个while循环,它允许主线程更新UILabel

while (ftp.AsyncFinished != YES) { 
    // here is the code getting data from the cilkat FTP module stored in PercentOfFile and MinutesRemaining 
    NSString *content =[[NSString alloc] initWithFormat:@"%.0f%% done%.0fmin left",PercentOfFile,MinutesRemaining ]; 
    [LabelProgress setText:content]; 
} 
+4

http://stackoverflow.com/questions/6363828/updating-uilabel-in-the-middle-of-a-for-loop – Habib

+0

@ Habbib.OSU注意'runMode:beforeDate:'方法是相当危险的。基于GCD,我为这个问题增加了一个更好的解决方案。 –

回答

1

你需要打电话给你的上传进度在另一个线程并注册回调。创建从CkoFTP2Progress继承具有这种方法的自定义类:

- (void)PercentDone: (NSNumber *)pctDone abort:(BOOL *)abort; 

假设你有一个名为“FTP”,并命名为“上传进度”您的自定义类CkoFTp2对象,注册回调:

[self.ftp setEventCallbackObject:self.uploadProgress]; 
0

你可以while循环移动到后台线程,并从那里与performSelectorOnMainThread调用的setText。

+1

...或者只是在更新标签的主线程中运行计时器。 – Till

+0

由于连接到外部FTP模块,因此将while循环移到背景处理是不可能的。我怎样才能做到这一点与计时器? – Jan

4

为了使UI在所有更新,主线程的运行循环已完成。这意味着你的方法(如果在主线程上调用)必须在任何UI更新发生之前返回。所有更新然后合并并重新绘制UI。

更多背景信息,请参阅What is the most robust way to force a UIView to redraw?

while回路设计错误的异步更新。您不应该在while循环中获取异步数据。您应该注册某种回拨(通常将自己设置为delegate),然后等待系统给您打电话。

0
// update your UILabel here 
// ... 

// Delay execution of long-running task so that update of UILabel can be performed 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
    // long-running task 
    // .. 
});