多线程之NSThread的使用
1.NSThread创建方式一
//开启了一个子线程,主线程继续执行,子线程也继续执行
//这种方式创建无法取得当前的线程对象`这里写代码片`
[NSThread detachNewThreadSelector:@selector(thread:) toTarget:self withObject:nil];
Demo:
- (void)viewDidLoad {
[super viewDidLoad];
//开启了一个子线程,主线程执行,子线程也继续执行
[NSThread detachNewThreadSelector:@selector(text1) toTarget:self withObject:nil];
//主线程
[self text2];
}
- (void)text1
{
for (int i = 0; i < 1000; i ++)
{
//性能开销比较大
NSLog(@"task 1 : %d",i);
}
}
- (void)text2
{
for (int i = 0; i < 100; i ++)
{
//性能开销比较大
NSLog(@"task 2 : %d",i);
}
}
打印结果为:
2015-04-07 14:29:15.257 NSTread[29473:2203350] task 2 : 0
2015-04-07 14:29:15.257 NSTread[29473:2204215] task 1 : 0
2015-04-07 14:29:15.257 NSTread[29473:2203350] task 2 : 1
2015-04-07 14:29:15.257 NSTread[29473:2204215] task 1 : 1
2015-04-07 14:29:15.258 NSTread[29473:2203350] task 2 : 2
.
.
.
task 1和task 2交互打印
2.NSThread创建方式二
//创建线程,并且设置了多线程的入口方法thread:
//用alloc方法创建的子线程要手动开启线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(thread:) object:@"test"];
Demo:
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(text1) object:nil];
//手动开启线程
[thread start];
//主线程
[self text2];
}
- (void)text1
{
for (int i = 0; i < 200; i ++)
{
//性能开销比较大
NSLog(@"task 1 : %d",i);
}
}
- (void)text2
{
for (int i = 0; i < 100; i ++)
{
//性能开销比较大
NSLog(@"task 2 : %d",i);
}
}
打印结果同1.
3.NSThread创建方式三
//开启后台线程(子线程)
[self performSelectorInBackground:@selector(thread:) withObject:@"thread--3"];
Demo 1:
- (void)viewDidLoad {
[super viewDidLoad];
//设置图片
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 100, 200, 200)];
imgView.backgroundColor = [UIColor grayColor];
[self.view addSubview:imgView];
}
#pragma mark - 设置图片
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//开启后台线程(子线程)
[self performSelectorInBackground:@selector(subThread:) withObject:nil];
}
- (void)subThread:(NSNumber *)number
{
//ARC,因为在子线程创建的自动释放池的对象是不能够入主线程的自动释放池中
@autoreleasepool {
NSLog(@"current Thread : %@",[NSThread currentThread]);
//耗时操作
NSURL *url = [NSURL URLWithString:@"http://img4.imgtn.bdimg.com/it/u=960422317,3273871593&fm=21&gp=0.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//不能在子线程中刷新UI,很有可能会崩溃
//imgView.image = image;
//只能在主线程做刷新UI,涉及到主线程和子线程通信(NSObject中的方法)
[self performSelectorOnMainThread:@selector(refreshUI:) withObject:image waitUntilDone:YES];
/*
假设子线程还有若干事情
YES:必须走完refreshUI:
NO:主线程继续执行,子线程也接着执行
一般还是选择用YES
*/
}
}
- (void)refreshUI:(UIImage *)image
{
imgView.image = image;
}
Demo 2:
//开启后台线程(子线程)
[self performSelectorInBackground:@selector(thread:) withObject:@"thread--3"];
for (int i=0; i<50; i++) {
NSLog(@"主--线程:i:%d",i);
}
}
- (void)thread:(NSString *)str {
NSLog(@"str:%@",str);
for (int i=0; i<50; i++) {
NSLog(@"多线程:i:%d",i);
if (i == 20) {
//退出当前的线程
[NSThread exit];
//设置当前线程睡眠一段时间
[NSThread sleepForTimeInterval:5];
}
}
//取得当前的线程
NSThread *thread = [NSThread currentThread];
NSLog(@"当前的线程:%@",thread);
//判断当前线程是不是多线程
if (![NSThread isMainThread]) {
NSLog(@"--------是多线程");
}
}
@end