• 1.多线程-NSThread


    1.在主线程执行多次NSLog模拟耗时操作

    结果,卡住主线程

    解决方案: performSelectorInBackground让程序在后台执行
     
    2.pthread的使用
    开辟子线程,执行一个函数
    __bridge桥接,OC对象和C指针之间的转换
    {  /*
            参数1:线程的编号(地址)
            参数2:线程的属性 NULL nil(oc)
            参数3:要调用的函数 void *  (*)  (void *)
            参数4:给要调用的函数传递的参数
         */
        //开辟新的线程
        pthread_t ID;
        NSString *str = @"ls";
        //__bridge桥接 类型转换(oc - 》c)
        //MRC 谁创建,谁释放
        //ARC 自动管理
        int result = pthread_create(&ID, NULL, demo, (__bridge void *)(str));
        //result 0 代表成功 其他代表失败
        if (result == 0) {
            NSLog(@"成功");
        }else
        {
            NSLog(@"失败");
        }
        
    }
    /**
        pthread调用的函数
     */
    void * demo(void * param)
    {
        NSString *Str = (__bridge NSString *)(param);
        //获取当前的代码执行在哪个线程当中,获取当前线程
        NSLog(@"%@ %@",Str,[NSThread currentThread]);
        return NULL;
    }

    3.NSThread的3种使用方式

    {   //创建
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
        //调用
        [thread start];
        
    //    //方式2
        [NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:nil];
        
        //方式3
        [self performSelectorInBackground:@selector(demo) withObject:nil];
        
        //传递参数
        [self performSelectorInBackground:@selector(demo2:) withObject:@"HM"];
        
    }
    - (void)demo2:(NSString *)str
    {
        NSLog(@"%@ %@",str,[NSThread currentThread]);
    }
    /**
        要调用的方法
     */
    - (void)demo
    {
        NSLog(@"%@",[NSThread currentThread]);
    }

    4.线程的生命周期

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //新建状态
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
        //就绪状态
        [thread start];
        
        //运行状态:系统控制的
        
        
    }
    - (void)demo
    {
        for (int i = 0; i <20; i++) {
            
            if (i == 5) {
                //阻塞状态
                //让当前的线程睡一段时间
                [NSThread sleepForTimeInterval:3];
            }else if (i == 10)
            {
                //死亡状态
                [NSThread exit];
            }
            NSLog(@"%d",i);
        }
    }

    5.NSThread的属性,可以设置属性的名称、优先级

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //线程属性
        //主线程占用的内存空间
        NSLog(@"%zd",[NSThread currentThread].stackSize/1024);
        //创建线程1
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
        //设置线程名称
        thread.name = @"t1";
        //设置线程的优先级 参数的取值范围 0-1  0是优先级最低的,1是优先级最高 默认的是0.5
        [thread setThreadPriority:1.0];
        [thread start];
        
        //创建线程2
        NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
        //设置线程名称
        thread2.name = @"t2";
        [thread2 setThreadPriority:0.0];
        [thread2 start];
        
        //设置线程的优先级不能绝对保证线程优先执行,但是线程被调用的概率提高
        
    }
    - (void)demo
    {
        
        //子线程占用的内存空间
        NSLog(@"demo  %zd",[NSThread currentThread].stackSize/1024);
    //    NSLog(@"%@",[NSThread currentThread]);
        for (int i = 0; i < 10; i++) {
            NSLog(@"%d %@",i,[NSThread currentThread].name);
            
        }
        
    }

    6.线程间资源抢夺的时候,需要加互斥锁(锁住一个对象)

    #import "ViewController.h"
    
    @interface ViewController ()
    //总票数
    @property(nonatomic,assign)int totalTickets;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //设置票数为20
        self.totalTickets = 20;
        
    }
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //窗口1 模拟卖票
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
        thread.name = @"t1";
        [thread start];
        
        
        //窗口2 模拟卖票
        
        NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
        thread2.name = @"t2";
        [thread2 start];
    }
    /**
        卖票
     */
    - (void)sellTickets
    {
        while (YES) {
            //被加锁的对象
            @synchronized(self) {
                //查询剩余的票数,判断
                if (self.totalTickets > 0) {
                    self.totalTickets = self.totalTickets - 1;
                    NSLog(@"剩余%d票 %@",self.totalTickets,[NSThread currentThread].name);
                }else
                {
                    NSLog(@"票卖完了,回不了家,走路回家");
                    break;
                }
            }
           
        }
    }

    7.异步下载图片,在子线程下载图片,在主线程更新UI

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //网络图片下载
        /*
                1.不能把耗时操作放到主线程中,开辟新的线程
                2.刷新ui一定要在主线程
    //     http://g.hiphotos.baidu.com/image/pic/item/f31fbe096b63f624cd2991e98344ebf81b4ca3e0.jpg
         */
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImg) object:nil];
        [thread start];
        
        
    }
    /**
        下载图片
     */
    - (void)downloadImg
    {
        NSLog(@"downloadImg %@",[NSThread currentThread]);
        //获取链接地址
        NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f31fbe096b63f624cd2991e98344ebf81b4ca3e0.jpg"];
        //转化NSData类型
        NSData *data = [NSData dataWithContentsOfURL:url];
        //转化成UIImage
        UIImage *img = [UIImage imageWithData:data];
        
        /*
            参数1:主线程要调用的方法
            参数2:给调用的方法传递的参数
            参数3:是否等待当前代码执行完毕再来执行下面的代码
         */
        [self performSelectorOnMainThread:@selector(updataUI:) withObject:img waitUntilDone:YES];
        NSLog(@"end");
        
    }
    /**
        刷新ui ui刷新必须放到主线程里面
     */
    - (void)updataUI:(UIImage *)img
    {
        NSLog(@"updataUI %@",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:3];
        self.HMImageView.image = img;
    }
  • 相关阅读:
    Eclipse汉化教程
    php课程---文件操作及文件上传的代码总结
    php课程---Json格式规范需要注意的小细节
    php课程---php使用PDO方法详解(转)
    php课程---随机数
    php课程---Ajax(老师详解)
    php课程---JavaScript与Jquery的区别
    php课程---JavaScript与Jquery的区别(转)
    php课程---初学PDO
    php课程---练习(联系人信息表)
  • 原文地址:https://www.cnblogs.com/fanglove/p/5215180.html
Copyright © 2020-2023  润新知