• iOS UI-线程(NSThread)及其安全隐患与通信


    一、基本使用

    1.多线程的优缺点

    多线程的优点
    能适当提高程序的执行效率
    能适当提高资源利用率(CPU、内存利用率)
    多线程的缺点
    开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
    线程越多,CPU在调度线程上的开销就越大
    程序设计更加复杂:比如线程之间的通信、多线程的数据共享
     
     
    2.多线程在iOS开发中的应用
    什么是主线程
    一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
     
    主线程的主要作用
    显示刷新UI界面
    处理UI事件(比如点击事件、滚动事件、拖拽事件等)
     
    主线程的使用注意
    别将比较耗时的操作放到主线程中
    耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验
     
     
      1 //
      2 //  ViewController.m
      3 //  IOS_0116_NSThread
      4 //
      5 //  Created by ma c on 16/1/16.
      6 //  Copyright (c) 2016年 博文科技. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 #import <pthread.h>
     11 
     12 /*
     13  线程的实现方案
     14  pthread
     15  NSThread
     16  GCD
     17  NSOperation
     18  */
     19 @interface ViewController ()
     20 
     21 @end
     22 
     23 @implementation ViewController
     24 
     25 
     26 - (void)viewDidLoad {
     27     [super viewDidLoad];
     28     
     29     //[self pthread];
     30     
     31 }
     32 #pragma mark - 创建线程NSThread
     33 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
     34 {
     35 //    [self createThread1];
     36 //    [self createThread2];
     37     [self createThread3];
     38 
     39 }
     40 #pragma mark - 创建线程3
     41 - (void)createThread3
     42 {
     43     //隐式创建线程
     44     [self performSelector:@selector(download:) withObject:@"http:www.bowen.cn"];
     45     [self download:@"http:www.bowen.cn"];
     46     
     47     [self performSelectorInBackground:@selector(download:) withObject:@"http:www.bowen.cn"];
     48     
     49     [self performSelector:@selector(download:) onThread:[NSThread mainThread] withObject:@"http:www.bowen.cn" waitUntilDone:nil];
     50     
     51 }
     52 
     53 
     54 #pragma mark - 创建线程2
     55 - (void)createThread2
     56 {
     57     //创建后并启动线程
     58     [NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http:www.bowen.cn"];
     59 }
     60 - (void)download:(NSString *)url
     61 {
     62     NSLog(@"
    download----%@",[NSThread mainThread]);
     63 
     64     
     65     NSLog(@"
    download----%@----%@",url,[NSThread currentThread]);
     66 }
     67 
     68 #pragma mark - 创建线程1
     69 //启动线程 - 进入就绪状态 -(CPU调度当前线程)- 运行状态 - 线程任务完毕,自动进入死亡状态
     70 //                                               -调用sleep方法或者等待同步锁 - 阻塞状态
     71 - (void)createThread1
     72 {
     73     //创建线程
     74     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download) object:nil];
     75     //设置线程的名字
     76     thread.name = @"下载线程";
     77     //当前线程是否是主线程
     78     [thread isMainThread];
     79     //启动线程
     80     [thread start];
     81     
     82     //判断当前方法是否是在主线程主线程中执行
     83     [NSThread isMainThread];
     84 }
     85 
     86 - (void)download
     87 {
     88     NSLog(@"
    download----%@",[NSThread mainThread]);
     89     
     90     //阻塞线程
     91     [NSThread sleepForTimeInterval:3];
     92     [NSThread  sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
     93     
     94     NSLog(@"
    download----%@",[NSThread currentThread]);
     95     
     96     //强制停止线程
     97     [NSThread exit];
     98     NSLog(@"
    download----%@",@"exit");
     99 }
    100 
    101 
    102 #pragma mark - pthread
    103 - (void)pthread
    104 {
    105     NSLog(@"
    viewDidLoad-------%@",[NSThread currentThread]);
    106     
    107     //创建线程
    108     pthread_t myRestrict;
    109     pthread_create(&myRestrict, NULL, run, NULL);
    110 }
    111 
    112 void *run(void *data)
    113 {
    114     NSLog(@"
    run-------%@",[NSThread currentThread]);
    115     
    116     return NULL;
    117 }
    118 
    119 @end

    二、线程安全

     1 //
     2 //  ViewController.m
     3 //  IOS_0117_线程的安全隐患
     4 //
     5 //  Created by ma c on 16/1/17.
     6 //  Copyright (c) 2016年 博文科技. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 @interface ViewController ()
    12 
    13 @property (nonatomic, strong) NSThread *thread1;
    14 @property (nonatomic, strong) NSThread *thread2;
    15 
    16 //剩余票数
    17 @property (nonatomic, assign) int leftTicketCount;
    18 
    19 @end
    20 
    21 @implementation ViewController
    22 /*
    23  资源共享
    24  一块资源可能会被多个线程共享,也就是多个线程可能会访问[同一块资源]
    25  
    26  比如多个线程访问同一个对象、同一个变量、同一个文件
    27  
    28  当多个线程访问同一块资源时,很容易引发[数据错乱和数据安全]问题
    29 
    30  */
    31 
    32 - (void)viewDidLoad {
    33     [super viewDidLoad];
    34     
    35     self.leftTicketCount = 50;
    36     
    37     self.thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    38     self.thread1.name = @"1号窗口";
    39     self.thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    40     self.thread2.name = @"2号窗口";
    41     
    42     
    43 }
    44 
    45 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    46 {
    47     [self.thread1 start];
    48     [self.thread2 start];
    49 }
    50 /*
    51  互斥锁使用格式
    52  @synchronized(锁对象) { // 需要锁定的代码  }
    53  注意:锁定1份代码只用1把锁,用多把锁是无效的
    54  
    55  互斥锁的优缺点
    56  优点:能有效防止因多线程抢夺资源造成的数据安全问题
    57  缺点:需要消耗大量的CPU资源
    58  
    59  互斥锁的使用前提:多条线程抢夺同一块资源
    60  
    61  相关专业术语:线程同步
    62  线程同步的意思是:多条线程在同一条线上执行(按顺序地执行任务)
    63  互斥锁,就是使用了线程同步技术
    64 
    65  */
    66 - (void)saleTicket
    67 {
    68     while (1) {
    69         
    70         @synchronized(self){ //开始枷锁 小括号里面放的是锁对象
    71             int count = self.leftTicketCount;
    72             if (count>0) {
    73                 self.leftTicketCount = count -1;
    74                 NSLog(@"%@卖了一张票,剩余%d张票",[NSThread currentThread].name, self.leftTicketCount);
    75             }else{
    76                 return; //退出循环 break
    77             }
    78 
    79         }//解锁
    80         
    81     }
    82 }
    83 
    84 - (void)didReceiveMemoryWarning {
    85     [super didReceiveMemoryWarning];
    86     // Dispose of any resources that can be recreated.
    87 }
    88 
    89 @end

    三、线程间通信

     1 //
     2 //  ViewController.m
     3 //  IOS_0117_线程间通信
     4 //
     5 //  Created by ma c on 16/1/17.
     6 //  Copyright (c) 2016年 博文科技. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 @interface ViewController ()
    12 
    13 @property (nonatomic, strong) UIImageView *imgView;
    14 
    15 
    16 @end
    17 
    18 @implementation ViewController
    19 
    20 /*
    21  什么叫做线程间通信
    22  在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
    23  
    24  线程间通信的体现
    25  1个线程传递数据给另1个线程
    26  在1个线程中执行完特定任务后,转到另1个线程继续执行任务
    27  
    28  线程间通信常用方法
    29  - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    30  - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
    31 
    32  */
    33 - (void)viewDidLoad {
    34     [super viewDidLoad];
    35     
    36     self.imgView = [[UIImageView alloc] initWithFrame:CGRectMake(120, 100, 150, 250)];
    37     //self.imgView.image = [UIImage imageNamed:@"1.png"];
    38     self.imgView.backgroundColor = [UIColor cyanColor];
    39     [self.view addSubview:self.imgView];
    40     
    41     
    42 }
    43 
    44 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    45 {
    46     [self performSelectorInBackground:@selector(downloadPicture) withObject:nil];
    47     
    48 }
    49 
    50 - (void)downloadPicture
    51 {
    52     
    53     NSLog(@"
    download----%@",[NSThread currentThread]);
    54     //1.图片地址
    55     NSString *urlStr = @"1.png";
    56     //NSURL *url = [NSURL URLWithString:urlStr];
    57     //2.根据地址下载图片的二进制数据
    58     //NSData *data = [NSData dataWithContentsOfURL:url];
    59     //3.设置图片
    60     UIImage *image = [UIImage imageNamed:urlStr];
    61     //self.imgView.image = [UIImage imageWithData:data];
    62     //4.回到主线程,刷新UI界面(为了线程安全)
    63     [self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:YES];
    64 }
    65 - (void)downloadFinished:(UIImage *)image
    66 {
    67     
    68     NSLog(@"
    downloadFinished----%@",[NSThread currentThread]);
    69     self.imgView.image = image;
    70     
    71 }
    72 - (void)didReceiveMemoryWarning {
    73     [super didReceiveMemoryWarning];
    74     // Dispose of any resources that can be recreated.
    75 }
    76 
    77 @end
  • 相关阅读:
    英语八大时态
    linux yum被占用
    文件上传ajaxfileupload.js插件
    jquery.qrcode.js生成二维码
    判断手机,pc方式登录
    点击小图轮播,点击显示大图
    图片预览功能
    Java Hash表 数据结构
    Java Tree 树 数据结构
    Java Queue 队列
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5137146.html
Copyright © 2020-2023  润新知