iOS之线程的概念和NSThread(一)

本文深入探讨了iOS应用中的多线程技术,包括进程与线程的基础概念、NSThread的使用方法、线程间的通信机制、线程安全问题及解决策略。通过实例展示了如何创建子线程,解释了主线程的作用,并讨论了线程阻塞的概念。

1. 基础概念

1.1进程:一个运行的应用程序,就是一个进程(比如:你iphone上的QQ,微信,MAC电脑上的迅雷,Xcode等)
  • 每一个进程之间是相互独立的,在内存中开辟空间
  • 一个打开应用程序不一定是一个进程(比如:QQ程序,你开启多个QQ账号登录,就对应的多个进程)
线程:一个进程要执行任务的片段,一条进程至少要有一个线程
  • 一个应用程序的所有任务都要在线程中执行
多线程:是一个进程开启了多条线程,每条线程同时执行不同的任务
主线程
  • iOS程序运行之后,默认开启一条线程,成为主线程或者UI线程
  • 主线程是用来:刷新UI界面,处理UI事件
使用分类
技术简介语言周期
NSThread[1]面向对象 [2]可直接操作线程OC程序员自己管理 -> 偶尔使用
GCD[1]代替NSThread 【2】充分利用CPU多核C程序员自己管理 -> 使用次数频繁
NSOperation[1]基于GCD 【2】面向对象操作OC程序员自己管理 -> 使用次数频繁
2.NSThread 线程
2.1基础认知
  • 获取主线程
 NSThread *main = [NSThread mainThread];
    NSLog(@"%@",main);
   
  • 获取当前线程
  //获取当前线程
    NSThread *current = [NSThread currentThread];
    NSLog(@"-----%@",current);
  • 设置线程的名称属性name属性
  • 设置线程的优先级threadPriority属性,范围0.0-1.0 (默认是0.5)
2.2创建子线程 方法一
//开启一个线程
- (void)setupTh {
    /*
     *参数一:目标对象
     * 参数二:要执行的g方法
     * 参数三:要执行的方法需要传入的参数值
     */
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(handleThreadAction:) object:@"test"];
    //设置线程的名称
     thread.name = @"CC";
    //启动线程
    [thread start];
    
    
}

//要执行的方法
- (void)handleThreadAction:(NSString *)par {
    
    NSLog(@"---%@----%@",[NSThread currentThread],par);
}
//打印结果
 ---<NSThread: 0x600003495fc0>{number = 3, name = CC}----test


2.3 创建子线程 方法二
- (void)setupTwo {
    //参数和 方法一的参数 类似
    [NSThread detachNewThreadSelector:@selector(handleThreadAction:) toTarget:self withObject:@"text"];
 
}

- (void)handleThreadAction:(NSString *)par {
    NSLog(@"---%@----%@",[NSThread currentThread],par);
    NSLog(@"%@",[NSThread isMainThread] == YES ? @"是" :@"不是");
   
}

//打印
---<NSThread: 0x6000004da8c0>{number = 3, name = (null)}----text
06-03 16:26:23.173228+0800 01-线程[20338:241267] 不是

3. 隐式线程

- (void)setupThress {
    //开启一个后台子线程
    //这个方法的参数 和 上面创建子线程的类似
    [self performSelectorInBackground:@selector(handleThreadAction:) withObject:@"创建放大--"];
}

- (void)handleThreadAction:(NSString *)par {
    
    NSLog(@"---%@----%@",[NSThread currentThread],par);
    NSLog(@"%@",[NSThread isMainThread] == YES ? @"是" :@"不是");
}

NSThread线程的生命周期是,当任务执行完成才后被释放这个对象

4.线程的安全问题

出现这个问题的原因,一般为多人同时访问的共有资源的时候,会导致资源的覆盖或者资源数据出错(比如:售票)

4.1互斥(同步)锁
@synchronized ("全局属性") {
    //要枷锁的代码
}
  • 互斥锁的条件
    • 必须是全局唯一的对象
    • 多线程共享同一块资源
  • 互斥锁的结果
    • 线程同步执行
    • 耗费性能
- (void)saleoftickets{
    
    self.read1 = [[NSThread alloc] initWithTarget:self selector:@selector(handleThreadAction) object:nil];
  
    self.read2 = [[NSThread alloc] initWithTarget:self selector:@selector(handleThreadAction) object:nil];
    
    self.read3 = [[NSThread alloc] initWithTarget:self selector:@selector(handleThreadAction) object:nil];
    
     self.read1.name = @"售票TT";
    self.read2.name = @"售票CC";
    self.read3.name = @"售票BB";
    //启动线程
    [self.read1 start];
    //启动线程
    [self.read2 start];
    //启动线程
    [self.read3 start];
    
}

//执行方法

- (void)handleThreadAction{
    
    // synchronized 是消耗性能的,线程使用的锁对象 必须是同一个对象
    // 可以定义一个属性对象 
    while (1) {
        @synchronized (self) {
            
            for (int i = 0; i < 1000; i ++) {
                
            }
            
            NSUInteger accunt = self.acount;
            
            if (accunt > 0) {
                self.acount = accunt - 1;
                NSLog(@"%@----%ld",[NSThread currentThread].name,self.acount);
                
            }else {
                NSLog(@"售完了。。。。");
                break;
            }
            
        }
        
        
    }
    
   
}

4.2原子属性和非原子属性
  • nonatomic非原子属性,没有加互斥锁
  • atomic原子属性,为了线程安全,在setter 加互斥锁
5.线程之间的通信
  • 线程之间通信常用的方法

//在子线程中调用 这个方法 就是回到主线程 进行操作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait


// 从一个线程跳转到另外一个线程执行操作
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait;

主要用于:图片下载异步操作

6.线程阻塞

- (void)sleepThread {
    //阻塞2秒
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
    
    //阻塞到遥远的未来
    [NSThread sleepUntilDate:[NSDate distantFuture]];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值