iOS 在子线程运行performSelector和NSTimer

时间:2022-09-10 20:39:49

首先这个要涉及到NSRunLoop和概念,我就简单的说一下。一个主线程,它在调用自己或其他类的函数的时候需要NSRunLoop,而主线程则默认有NSRunLoop。但是子线程没有,所以当子线程调用其他函数的时候会失效,如果我们开启NSRunLoop就能使用,这个NSRunLoop并不是我们创建出来的,而是去借用主线程的。

先上代码,再说一下

//
// ViewController.m
// BmobTest
//
// Created by shanreal-iOS on 2017/12/9.
// Copyright © 2017年 shanreal.LongZhenHao. All rights reserved.
//

#import "ViewController.h"
#import "TestBean.h"
#import "MyTableViewCell.h"
#import "DetailTableViewCell.h"

@interface ViewController ()

@property(nonatomic,strong)UIButton* btn;
@property(nonatomic,strong)UIButton* btn2;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

_btn = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 100, 30)];
[_btn setTitle:@"button" forState:UIControlStateNormal];
[_btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_btn.font = [UIFont systemFontOfSize:20];

[_btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btn];

_btn2 = [[UIButton alloc]initWithFrame:CGRectMake(20, 60, 100, 30)];
[_btn2 setTitle:@"two" forState:UIControlStateNormal];
[_btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_btn2.font = [UIFont systemFontOfSize:20];

[_btn2 addTarget:self action:@selector(btn2Click) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btn2];

}

-(void)btnClick{

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{



[self performSelector:@selector(backGroundThread) onThread:[NSThread currentThread] withObject:nil waitUntilDone:NO];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];

});

}

- (void)backGroundThread{

NSLog(@"%u",[NSThread isMainThread]);

NSLog(@"execute %s",__FUNCTION__);

}

-(void)btn2Click{

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{



NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];

[myTimer fire];

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];
});

}
- (void)timerAction{

NSLog(@"timer action");

}
@end

这个NSRunLoop一定要放在执行的函数后面,如果不这样做,可能不会执行函数。我在想可能是跳转函数后,才会需要NSRunLoop,而不是跳转前去准备。