iOS子線程更新UI到主線程的三種方法

代碼同步到主線程執(zhí)行的三種方法如下:

// 1.NSThread
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];

- (void)updateUI {
    // UI更新代碼
    self.alert.text = @"Thanks!";
}

// 2.NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // UI更新代碼
    self.alert.text = @"Thanks!";
    }];

// 3.GCD
dispatch_async(dispatch_get_main_queue(), ^{
   // UI更新代碼
   self.alert.text = @"Thanks!";
});

看下面的例子: 以下代碼有什么問(wèn)題?如何修復(fù)?

@interface TTWaitController : UIViewController

@property (strong, nonatomic) UILabel *alert;

@end

@implementation TTWaitController

- (void)viewDidLoad
{
    CGRect frame = CGRectMake(20, 200, 200, 20);
    self.alert = [[UILabel alloc] initWithFrame:frame];
    self.alert.text = @"Please wait 10 seconds...";
    self.alert.textColor = [UIColor whiteColor];
    [self.view addSubview:self.alert];

    NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];
    [waitQueue addOperationWithBlock:^{
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
        self.alert.text = @"Thanks!";
    }];
}

@end

@implementation TTAppDelegate

- (BOOL)application:(UIApplication *)application
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = [[TTWaitController alloc] init];
    [self.window makeKeyAndVisible];
    return YES;
}

這段代碼是想提醒用戶等待10s,10s后在標(biāo)簽上顯示“Thanks”,但多線程代碼部分NSOperationQueue的addOperationWithBlock函數(shù)不能保證block里面的語(yǔ)句是在主線程中運(yùn)行的,UILabel顯示文字屬于UI更新,必須要在主線程進(jìn)行,否則會(huì)有未知的操作,無(wú)法在界面上及時(shí)正常顯示。

解決方法是將UI更新的代碼寫(xiě)在主線程上即可,代碼同步到主線程上主要有三種方法:NSThread、NSOperationQueue和GCD,三個(gè)層次的多線程都可以獲取主線程并同步。

NSThread級(jí)主線程同步:performSelectorOnMainThread

NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];
[waitQueue addOperationWithBlock:^{
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    // 同步到主線程
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
}];

/**
 * UI更新函數(shù)
 */
- (void)updateUI {
    self.alert.text = @"Thanks!";
}

NSOperationQueue級(jí)主線程同步:[NSOperationQueue mainQueue]

NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];
[waitQueue addOperationWithBlock:^{
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    // 同步到主線程
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.alert.text = @"Thanks!";
    }];
}];

GCD級(jí)主線程同步:dispatch_get_main_queue

NSOperationQueue *waitQueue = [[NSOperationQueue alloc] init];
[waitQueue addOperationWithBlock:^{
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    // 同步到主線程
    dispatch_async(dispatch_get_main_queue(), ^{
        self.alert.text = @"Thanks!";
    });
}];

參考:https://blog.csdn.net/cordova/article/details/54933729

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS多線程實(shí)踐中,常用的就是子線程執(zhí)行耗時(shí)操作,然后回到主線程刷新UI。在iOS中每個(gè)進(jìn)程啟動(dòng)后都會(huì)建立一個(gè)主線...
    jackyshan閱讀 1,576評(píng)論 2 12
  • Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼,方法是什么?如果想延時(shí)執(zhí)行代碼、方法又是什么? 1...
    AlanGe閱讀 1,929評(píng)論 0 17
  • 原文地址 http://www.cnblogs.com/kenshincui/p/3983982.html 大家都...
    怎樣m閱讀 1,431評(píng)論 0 1
  • 你好,我叫于秋宇。一個(gè)擅長(zhǎng)自我麻醉的懶人,今年大三,來(lái)自一個(gè)排不上名的學(xué)校,一個(gè)沒(méi)有前景的專業(yè)。 馬上就要過(guò)我...
    593b67556346閱讀 212評(píng)論 0 0
  • 老師, 您就像是冬日里的一抹陽(yáng)光 溫暖我的身心 您就像是黑暗中的一絲亮光 帶我闖出黑暗 找到光明 但是, 您卻為我...
    櫻花落ww閱讀 208評(píng)論 0 2

友情鏈接更多精彩內(nèi)容