iOS子线程更新UI到主线程的三种方法

来源:互联网 发布:安卓7.0 java模拟器 编辑:程序博客网 时间:2024/05/21 00:52

简单说将代码同步到主线程执行的三种方法如下:

// 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.GCDdispatch_async(dispatch_get_main_queue(), ^{   // UI更新代码   self.alert.text = @"Thanks!";});

看下面的例子:
以下代码有什么问题?如何修复?

@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后在标签上显示“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!";    });}];
1 0
原创粉丝点击