为什么延迟线程响应修复视图损坏?

时间:2010-03-29 01:17:26

标签: iphone cocoa-touch multithreading viewdidload

我的非常简单的iPhone应用程序中有6次在启动时显示损坏或随机崩溃。但它在模拟器中表现良好。显示器损坏看起来像错误的字体,不合适的字体文本,错误的背景颜色等。

我发现了一个奇怪的解决方法......当我的线程在调用“完成”通知之前延迟2秒时,一切都在顺畅地进行。线程读取一个网页,“完成”通知加载带有字符串的PickerView。什么给出了什么?我可以不安全地从viewDidLoad启动线程化任务吗?

- (void) loadWebPage:(NSString *)urlAddition {
      NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init];
      NSString *pageSource;
      NSError *err;
      NSString *urlString = [NSString stringWithFormat:@"http://server/%@",
                             urlAddition];
      pageSource = [NSString stringWithContentsOfURL:[NSURL URLWithString: urlString] 
                                            encoding:NSUTF8StringEncoding 
                                               error:&err];

      [NSThread sleepForTimeInterval:2.0]; // THIS STOPS THE DISPLAY CORRUPTION
      [[NSNotificationCenter defaultCenter] postNotificationName:@"webDoneNotification" 
                                                          object:nil]; 
      [subPool drain];
}

- (void) webDoneNotification: (NSNotification *)pNotification { 
      [mediaArray release];
      mediaArray = [[NSArray arrayWithObjects:
                     [NSString stringWithString:@"new pickerview text"], 
                     nil] retain];

      [mediaPickerView reloadAllComponents];

      [mediaPickerView selectRow:0 
                     inComponent:0 
                        animated:NO];
}


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
   mediaArray = [[NSArray arrayWithObjects:
                 [NSString stringWithString:@"init pickerview text"], 
                 nil] retain];

   if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad {
   [super viewDidLoad];

   myWebThread = [[WebThread alloc] initWithDelegate:self];
   [[NSNotificationCenter defaultCenter] addObserver:self 
                                            selector:@selector(webDoneNotification:) 
                                                name:@"webDoneNotification" 
                                              object:nil]; 
   [myWebThread performSelectorInBackground:@selector(loadWebPage:) withObject:@""];
}

谢谢!

更新:即使延迟0.1秒也足以完全解决问题。

1 个答案:

答案 0 :(得分:3)

您正在从后台线程更新视图。这就是造成你问题的原因; UIKit视图不是线程安全的。当您需要更改视图时,请在主线程中执行此操作。