Iphone ConnectiondFinishLoading-如何强制更新UIView?

Iphone ConnectiondFinishLoading-如何强制更新UIView?,iphone,nsurlconnection,Iphone,Nsurlconnection,我可以从网上下载一个ZIP文件。后处理在ConnectiondFinishLoading中完成,工作正常,但未更新UIView元素。例如,我设置了statusUpdate.text=@“解压缩文件”,但直到完成ConnectiondFinishLoading之后,才会显示该更改。类似地,直到此方法结束,UIProgressView和UIActivityIndicatorView对象才会更新 有没有办法从这个方法中强制更新UIView?我尝试设置[self.view setNeedsDisplay

我可以从网上下载一个ZIP文件。后处理在ConnectiondFinishLoading中完成,工作正常,但未更新UIView元素。例如,我设置了statusUpdate.text=@“解压缩文件”,但直到完成ConnectiondFinishLoading之后,才会显示该更改。类似地,直到此方法结束,UIProgressView和UIActivityIndicatorView对象才会更新

有没有办法从这个方法中强制更新UIView?我尝试设置[self.view setNeedsDisplay],但没有成功。它似乎正在主线程中运行。这里的所有其他命令都可以正常工作-唯一的问题是更新UI

谢谢

更新:以下是不更新UIVIEW的代码:

-(void)viewWillAppear:(BOOL)animated {
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(processUpdate:) userInfo:nil repeats:YES];
    downloadComplete = NO;
    statusText.text = @"";

}

-(void)processUpdate:(NSTimer *)theTimer {
    if (! downloadComplete) {
        return;
    }

    [timer invalidate];
    statusText.text = @"Processing update file."; 
    progress.progress = 0.0;
        totalFiles = [newFiles count];
    for (id fileName in newFiles) {
        count++;
            progress.progress = (float)count / (float)totalFiles;
        // ... process code goes here ...
         }
}
在processUpdate的最后,我将downloadComplete设置为YES。这将生成并运行无错误,并按预期工作,除了在UIVIEW中没有任何更新,直到processUpdate完成后,所有内容都会立即更新


谢谢你迄今为止的帮助

当您处于连接状态时,在应用程序运行循环中不会发生任何其他情况。控件需要传递回运行循环,以便它能够协调UI更新

只需将数据传输标记为完成,并将视图标记为更新。将下载数据的任何繁重处理延迟到它自己的线程


应用程序将回调您的视图,让它们稍后在运行循环中刷新其内容。根据需要在您自己的自定义视图上实现drawRect。

如果您在主线程中接收到ConnectiondFinishLoading,那么您就倒霉了。除非从该方法返回,否则UI中不会刷新任何内容

另一方面,如果在单独的线程中运行连接,则可以使用以下代码安全地更新UI:

UIProgressView *prog = ... <your progress view reference> ...
[prog performSelectorOnMainThread:@selector(setProgress:)
                       withObject:[NSNumber numberWithFloat:0.5f]
                    waitUntilDone:NO];
UIProgressView*prog=。。。
[prog performSelectorOnMainThread:@selector(setProgress:)
withObject:[NSNumber numberWithFloat:0.5f]
waitUntilDone:没有];

小心不要从非主线程更新UI-始终使用
performselectornmainthread
方法

正如Niels所说,如果您想看到视图更新,必须将控制权返回到run循环。但是不要开始分离新线程,除非你真的需要。我建议采取这种办法:

- (void)connectionDidFinishLoading:(NSConnection *)connection {
    statusUpdate.text = @"Uncompressing file";
    [self performSelector:@selector(doUncompress) withObject:nil afterDelay:0];
}

- (void)doUncompress {
    // Do work in 100 ms chunks
    BOOL isFinished = NO;
    NSDate *breakTime = [NSDate dateWithTimeIntervalSinceNow:100];
    while (!isFinished && [breakTime timeIntervalSinceNow] > 0) {
        // do some work
    }
    if (! isFinished) {
        statusUpdate.text = // here you could update with % complete
        // better yet, update a progress bar
        [self performSelector:@selector(doUncompress) withObject:nil afterDelay:0];
    } else {
        statusUpdate.text = @"Done!";
        // clean up
    }
}
基本的想法是,你可以分小块工作。您可以从方法返回,以允许定期执行运行循环。对performSelector:的调用将确保控件最终返回到对象

请注意,这样做的风险在于,用户可能会按一个按钮,或以您可能无法预料的方式与UI交互。调用UIApplication的
beginIgnoringInteractionEvents
在工作时忽略输入可能会有所帮助。。。除非你想表现得很好,并提供一个取消按钮来设置你在
doUncompress
方法中签入的标志


您也可以尝试自己运行运行循环,经常调用
[[NSRunLoop currentRunLoop]runUntilDate:…]
,但我从未在自己的代码中尝试过这一点。

完全按照使用计时器所做的操作,只需将处理代码分派到具有ConnectiondFinish:。计时器可以更新UI,因为它们是从主线程运行的。

问题是,UI没有在
for()
循环中更新。有关简单的解决方案,请参阅

谢谢你的回复!我实现了如上所述(复制和粘贴),但它挂起在while()循环中,从未进入它。我在模拟器上运行这个。知道它为什么挂起了吗?我的循环条件错了(应该是
>0
而不是
<0
)。我确定了我的答案;也许这就是你代码的问题所在?否则我没有足够的信息告诉你。不客气。请花点时间投票选出有用的答案,并将其中一个标记为已接受(绿色复选标记)。对不起,我错了,这仍然不起作用。(我的更新文件没有需要更新的内容,因此退出得太快了。)我在主循环中设置了一个计时器,以便在下载完成后运行processUpdate。我检查了,它正在主线程中运行,但它仍然没有更新UI。同样,这是在下载完成之后。其他一切都正常,只是UI更新(进度条、文本字段文本等)不正常。我甚至编写了一个虚拟例程来更新一个假的progressbar,并从几个不同的地方调用它,但都没有成功。还有其他想法吗?没有代码很难说。考虑编辑你的问题,并包括不可用的虚拟下载源。