zoukankan      html  css  js  c++  java
  • 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"];
    
  • 相关阅读:
    团队开发冲刺第十五天
    团队开发冲刺第十四天
    团队开发冲刺第十三天
    团队开发冲刺第十二天
    团队开发冲刺第十一天
    团队开发冲刺第十天
    幸运抽奖案例
    java中如何数组是如何赋值的?
    使用java中的String类操作复杂的字符串
    java中随机生成26个字母组合的随机验证码
  • 原文地址:https://www.cnblogs.com/KrystalNa/p/4780308.html
Copyright © 2011-2022 走看看