update ui while running in a loop
I have a read-only text field that I use as a log display. I have a operation that removes all the files in app's document directory. I want to insert a line of log when I remove each file. But the text field is o开发者_如何学编程nly updated when the whole operation got finished. How do I fix this?
Here is my code:
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];
}
You need to move your long-running operation into a background thread/queue and make sure that your UI-updating code is always executed on the main thread.
Example:
- (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];
}
You would then start your operation using:
[self performSelectorInBackground:@selector(processFiles:) withObject:files];
Using Grand Central Dispatch with blocks would be another option.
Refer to the Threading Programming Guide and the Concurrency Programming Guide for more in-depth information.
You need to look into Threading and making that call Asynchronous. You are currently blocking your main thread (assuming it's called from there). You need to separate the two so a separate thread does the heavy operation while your main thread is updated with the new text in the UI.
I've just started ios dev but sounds like you need to redraw that UIText I'm not sure how though I'd assume that when your log writes that you could dealloc your original UIText object the realloc it and it should redraw with the new log message. Only problem is that it will most likely update very very fast so redrawing wouldnt be worth it unless ios has a sleep function?
Something like: Alloc and init text Then in for loop after each write or new message in log dealloc your text and realloc and init your text
This should redraw the UIText object and update the text, if it doesnt expect a memory write error/app crash
精彩评论