01-线程的基本概念

线程的基本概念


主线程(UI线程)

  • 1.如何获取主线程
    • 如果是主线程,那么名称叫做main/number = 1
    • 如果不是主线程,那么名称就不叫座main/number != 1
    • 注意:currentThread代表拿到当前线程,如果但前执行的方法是被主线程执行的,那么拿到的就是主线程,如果不是被主线程执行的,那么拿到的就不是主线程
NSLog(@"%@",[NSThread currentThread]);

//明确的告诉系统,需要拿到主线程
NSLog(@"%@",[NSThread mainThread]);
  • 2.如何判断当前方法是否是在主线程中运行
if([NSThread isMainThread])
{
	NSLog(@"当前方法是在主线程中执行的");
}
  • 3.在主线程中执行耗时操作
    • 注意NSLog是非常消耗性能的操作
    • 点击button(执行以下耗时操作)同时操作UI控件(TextFiled) 会有卡顿
- (IBAction)btnOnClick:(id)sender
	for(int i = 0; i < 1000;i++)
	{
		//以后开发上架必须把NSLog都去掉
		NSLog(@"%i",i);
	}
}
耗时操作的处理方法
  • 耗时操作放到子线程中执行
    • 好处
      • 用户点击按钮的时候就有反应
      • 可以同时处理耗时操作和用UI控件的事件

多线程


iOS中多线程的实现方案(四种)

  • pthread(几乎不用)
    • C语言
    • 线程声明周期:程序员管理
  • NSThread(偶尔使用)
    • OC语言(更加面向对象)
    • 线程声明周期:程序员管理
  • GCD(取代NSThread,经常使用)
    • C语言
    • 可以充分利用设备的多核
    • 线程声明周期:自动管理
  • NSOperation(对GCD面向对象的封装)
    • 基于GCD(底层是GCD)
    • 比GCD多了一些更简单实用的功能
    • 使用更加面向对象
    • 线程声明周期:自动管理

Pthread的基本使用

  • 使用pthread创建子线程,把耗时操作放图子线程中
    • 创建一个Pthread就意味着开启了一个子线程(耗时9毫秒占用512kb内存)
  • 这时点击button在同时操作UI控件,不会卡顿
//导入头文件
#import <pthread/pthread.h>
void *demo(void *parm)
	{
		NSLog(@"%@",[NSThread currentThread]);
		NSLog(@"%s",parm);
		//耗时操作
		for(int i = 0; i < 1000;i++)
		{
			//以后开发上架必须把NSLog都去掉
			NSLog(@"%i",i);
		}
		return NULL;
	}

- (IBAction)btnOnClick:(id)sender
{
	//1.创建子线程
	/*
		第1个参数:线程代号(线程对象)
		第2个参数:(线程属性)
		第3个参数:void *(*)(void *)
					返回值(*指针名称)参数列表
					void * 相当于OC中的id
		第4个参数:给第三个参数传递的值
		C语言中的数据类型一般都是以 _t 或者Ref结尾
	*/
	
	//pthread_t 中已经包含*,所以不用再打了
	pthread_t threadId;
	pthread_creat(threadId,NULL,demo,"ln");
}

NSThread的基本使用

方法一:通过alloc init创建子线程
  • NSThread是OC的,是fundation框架中(可以使用alloc,init),(耗时9毫秒占用512kb内存)
  • 创建线程(使用alloc init需要手动启动start)
    • 设置线程名称(name)
      • 不设置默认打印出null
    • 设置线程的优先级(threadPriority,取值范围0.0~1.0 ,1.0最高,默认0.5)
      • 优先级高只是被CPU调度的可能性大,并不一定会先执行
NSThread *thread = [[NSThread alloc] initWihtTarget:self selector:@selector(demo:) objc:@"ln"];
[thread start];
  • 测试代码(点击button创建子线程)
(void) demo(NSString *)str
	{
		//NSLog(@"%@",[NSThread currentThread]);
		//NSLog(@"%@",str);
		//耗时操作:1分钟(主线程不会等)
		//for(int i = 0; i < 9000;i++)
		//{
		//	//以后开发上架必须把NSLog都去掉
		//	NSLog(@"%i",i);
		//}
		for(int i = 0; i < 9000;i++)
		{
		//优先级高只是被CPU调度的可能性大,并不一定会先执行
			NSLog(@"%i__%@",i,[NSThread currentThread]);
		}
	}

- (IBAction)btnOnClick:(id)sender
{
	//1.创建子线程
	/*
	Target :子线程需要调用谁的方法
	selector:被子线程调用的方法
	object:调用方法时,给方法传递的参数
	*/
	//注意:如果线程正在执行,那么系统会自动强引用NSThread
	//retained during the execution of the detached thread当线程中的任务执行完毕,系统会自动释放线程,对线程进行一次release操作
	
	NSThread *thread = [[NSThread alloc] initWihtTarget:self selector:@selector(demo:) objc:@"ln"];
	//若不设置名称娜默认为null
	thread.name = @"子线程1";
	//线程的优先级越高,那么被CPU调用的可能性就大
	//但并不代表着,优先级的高的一定会先执行
	thread.threadPriority = 0.0
	
	//2.启动线程(使用NSThread创建的线程必须手动启动)
	[thread start];
	
	//子线程2
	NSThread *thread2 = [[NSThread alloc] initWihtTarget:self selector:@selector(demo:) objc:@"ln"];
	thread2.name = @"子线程2";
	thread2.threadPriority = 1.0;
	[thread2 start];
	
	NSLog(@"主线程中当前的操作马上执行完毕了");
}

方法二:通过detach创建子线程
  • 创建子线程(通过detach)
    • 不需要手动调用start启动线程,系统会自动启动
    • 通过detach方法创建子线程是没有返回值的(不能设置名称,优先级)
  • 优点:
    • 使用简便
    • 通过detach,不需要手动调用start启动线程,系统会自动启动
  • 缺点
    • 不可以进行其他设置
    • 通过detach方法创建子线程是没有返回值的
  • 应用场景:
    • 如果仅仅需要简单的开启一个子线程执行一些操作,不需要对子线程进行其他设置,那么推荐使用detach方法创建线程
 NSThread *thread = [NSThread detachNewThreadSelector:(@selector:demo:) toTarget:self withObject:@"ln"];
方法三:通过perform创建子线程
//系统会自动在后台开启一个子线程,并且会自动启动该线程执行任务
[self performSelectorInBackground:@selector(demo:) wihtObject:@"ln"];
posted @ 2015-09-03 16:11  紫之灵玲  阅读(155)  评论(0编辑  收藏  举报