這段代碼是想提醒用戶等待10s,10s后在標簽上顯示“Thanks”,但多線程代碼部分NSOperationQueue的addOperationWithBlock函數不能保證block里面的語句是在主線程中運行的,UILabel顯示文字屬于UI更新,必須要在主線程進行,否則會有未知的操作,無法在界面上及時正常顯示。
解決方法是將UI更新的代碼寫在主線程上即可,代碼同步到主線程上主要有三種方法:NSThread、NSOperationQueue和GCD,三個層次的多線程都可以獲取主線程并同步。
NSThread級主線程同步:performSelectorOnMainThread
NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];[waitQueue addOperationWithBlock:^{ [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; // 同步到主線程 [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];}];/** * UI更新函數 */- (void)updateUI { self.alert.text = @"Thanks!";}NSOperationQueue級主線程同步:[NSOperationQueue mainQueue]
NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];[waitQueue addOperationWithBlock:^{ [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; // 同步到主線程 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.alert.text = @"Thanks!"; }];}];GCD級主線程同步:dispatch_get_main_queue
NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];[waitQueue addOperationWithBlock:^{ [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]]; // 同步到主線程 dispatch_async(dispatch_get_main_queue(), ^{ self.alert.text = @"Thanks!"; });}];
|
新聞熱點
疑難解答