iOS线程的实现: NSThread
2018-10-22 本文已影响13人
RyderZhang
线程间的通信:
在iOS开发过程中,我们一般在主线程里边进行UI刷新,例如:点击、滚动、拖拽等事件。我们通常把一些耗时的操作放在其他线程,比如说图片下载、文件上传等耗时操作。而当我们有时候在其他线程完成了耗时操作时,需要回到主线程,那么就用到了线程之间的通讯。
NSObject中多线程的方法:
开启后台执行任务的方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
在后台线程中通知主线程执行任务的方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
线程通信
[self performSelector:@selector(function) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
代码实例NSObjectFunc实现线程间的通信
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *buttonNames = @[@"阻塞主线程", @"看看卡不卡"];
for (NSInteger i=0; i<buttonNames.count; i++) {
UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(10, 200+70*i, self.view.frame.size.width-20, 30)];
[btn setTitle:buttonNames[i] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
btn.tag=100+i;
[btn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
}
-(void)buttonClick:(UIButton *)button{
if (button.tag == 100) {
//[self needLongTimeFuction];
/*performSelectorInBackground:withObject:
自动开辟一个子线程,让self在子线程中运行needLongTimeFuction方法
第一个参数:代表执行的方法
第二个参数:表示执行这个方法需要传的参数
*/
[self performSelectorInBackground:@selector(needLongTimeFuction) withObject:nil];
//[NSThread mainThread] 取到主线程 number=1代表主线程
//[NSThread currentThread] 取到当前线程
NSLog(@"%@", [NSThread mainThread]);
NSLog(@"%@", [NSThread currentThread]);
}
if (button.tag == 101) {
NSLog(@"不卡了!!!");
}
}
#pragma mark - 耗时操作
-(void)needLongTimeFuction{
//注意: 子线程最好放在自动释放池中
@autoreleasepool {
NSLog(@"%@", [NSThread currentThread]);
NSLog(@"耗时操作执行开始!!!");
//当前线程休眠多长时间,例如模拟请求网络数据
[NSThread sleepForTimeInterval:60.0];
NSLog(@"耗时操作执行结束!!!");
//耗时操作完成,如果需要刷新UI,必须要在主线程里刷新页面
//[self reloadCurrentPageUI];
/*
让self在主线程中执行reloadCurrentPageUI方法
第一个参数:执行的方法
第二个参数:执行方法所需要传递的参数
第三个参数:代表子线程是否需要等待主线程执行完成方法
*/
//[self performSelectorOnMainThread:@selector(reloadCurrentPageUI) withObject:nil waitUntilDone:YES];
/*让self在X线程中执行reloadCurrentPageUI的方法
第一个参数:执行的方法
第二个参数:在哪个线程中执行
第三个参数:执行方法需要传递的参数
第四个参数:代表当前线程是否需要等待X线程执行完成
*/
[self performSelector:@selector(reloadCurrentPageUI) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
}
}
#pragma mark - 刷新界面UI
-(void)reloadCurrentPageUI{
NSLog(@"UI刷新成功!!!");
}
NSThread Objective-C的线程类
1)创建线程,并自动执行
[NSThread detachNewThreadSelector:@selector(doSomeThing) toTarget:self withObject:nil];
2)创建线程,不自动执行
[[NSThread alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];
3)设置线程名
thread.name = @"另一个线程";
4)执行线程
[thread start];
5)函数内获取当前线程
[NSThread currentThread];
6)获取主线程
[NSThread mainThread];
7)线程休眠
[NSThread sleepForTimeInterval:1.0f]; // 休眠几秒
[NSThread sleepUntilDate:date]; // 休眠到指定时间
8)线程退出
[NSThread exit];
代码实例NSThread实现线程间的通信
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *buttonNames = @[@"阻塞主线程", @"看看卡不卡"];
for (NSInteger i=0; i<buttonNames.count; i++) {
UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(10, 200+70*i, self.view.frame.size.width-20, 30)];
[btn setTitle:buttonNames[i] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
btn.tag=100+i;
[btn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
}
-(void)buttonClick:(UIButton *)button{
if (button.tag == 100) {
//[self needLongTimeFuction];
/*创建一个子线程,让self去执行[self needLongTimeFuction]
第一个参数:谁去执行这个
第二个参数:执行哪个方法
第三个参数:执行方法所需要传递的参数
注意:这个方法需要手动去开启线程
*/
//NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(needLongTimeFuction) object:nil];
//手动开启线程
//[thread start];
//给线程取名字
//thread.name=@"SonThread";
/*用类方法创建一个子线程,执行[self needLongTimeFuction];
第一个参数:执行的方法
第二个参数:谁去执行
第三个参数:执行这个需要传递的参数
特点:会自动开启线程
*/
[NSThread detachNewThreadSelector:@selector(needLongTimeFuction) toTarget:self withObject:nil];
}
if (button.tag == 101) {
NSLog(@"不卡了!!!");
}
}
#pragma mark - 耗时操作
-(void)needLongTimeFuction{
//注意: 子线程最好放在自动释放池中
@autoreleasepool {
NSLog(@"%@", [NSThread currentThread]);
NSLog(@"耗时操作执行开始!!!");
//当前线程休眠多长时间,例如模拟请求网络数据
[NSThread sleepForTimeInterval:60.0];
NSLog(@"耗时操作执行结束!!!");
//耗时操作完成,如果需要刷新UI,必须要在主线程里刷新页面
//[self reloadCurrentPageUI];
[self performSelectorOnMainThread:@selector(reloadCurrentPageUI) withObject:nil waitUntilDone:YES];
//当前线程休眠多长时间
//[NSThread sleepForTimeInterval:10.0];
//返回B时间过去A秒之后的时间 [dateWithTimeInterval:A sinceDate:B]
//NSDate *date=[NSDate dateWithTimeInterval:10 sinceDate:[NSDate date]];
//当前线程休眠到某个时间
//[NSThread sleepUntilDate:date];
//退出当前线程
//[NSThread exit];
}
}
#pragma mark - 刷新界面UI
-(void)reloadCurrentPageUI{
NSLog(@"UI刷新成功!!!");
}
@end