在循环中运行时更新ui

时间:2011-10-09 09:24:42

标签: iphone cocoa-touch ipad uitextfield

我有一个只读文本字段,用作日志显示。我有一个删除应用程序文档目录中所有文件的操作。我想删除每个文件时插入一行日志。但是文本字段仅在整个操作完成时更新。我该如何解决这个问题?

这是我的代码:

NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
NSError *error = nil;
for (NSString *fileName in array) {
    NSString *filePath = [DOCUMENT_PATH_VALUE stringByAppendingFormat:@"/%@", fileName];
    [fm removeItemAtPath:filePath error:&error];

    if (!error) {
        NSString *log = [NSString stringWithFormat:@"removed success: %@", fileName];
        [self logThis:log];
    }else{
        NSString *log = [NSString stringWithFormat:@"remove failed: %@, %@", fileName, [error localizedDescription] ];
        [self logThis:log];

-(void)logThis:(NSString*) text{
    NSRange range = NSMakeRange([updateLogTextView.text length], [text length]);
    updateLogTextView.text = [updateLogTextView.text stringByAppendingFormat:@"%@\n", text]; 

    [updateLogTextView scrollRangeToVisible:range];
}

3 个答案:

答案 0 :(得分:0)

您需要查看Threading并调用异步。您当前正在阻止主线程(假设从那里调用它)。你需要将两者分开,这样一个单独的线程可以在你的主线程用UI中的新文本更新时进行繁重的操作。

答案 1 :(得分:0)

您需要将长时间运行的操作移动到后台线程/队列中,并确保您的UI更新代码始终在主线程上执行。

示例:

- (void)processFiles:(NSArray *)array
{
    //You need to create your own autorelease pool in background threads:
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    //...
    NSString *log = ...;
    [self performSelectorOnMainThread:@selector(logThis:) withObject:log waitUntilDone:NO];
    //...
    [pool release];
}

然后您将使用以下方式开始操作:

[self performSelectorInBackground:@selector(processFiles:) withObject:files];

使用带有块的Grand Central Dispatch将是另一种选择。

有关更深入的信息,请参阅Threading Programming GuideConcurrency Programming Guide

答案 2 :(得分:0)

我刚刚开始使用ios dev,但听起来你需要重新绘制UIText我不知道怎么样我会假设当你的日志写入你可以解除你的原始UIText对象时重新分配它并且它应该重绘使用新的日志消息。唯一的问题是它很可能会非常快地更新,所以重绘不值得,除非ios有睡眠功能吗?

像: Alloc和init文本 然后在每个写入或for message中的for循环中,在日志中释放你的文本并重新分配并初始化你的文本

这应该重绘UIText对象并更新文本,如果它不期望内存写入错误/应用程序崩溃