zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Python 学习日记 第七天
    Python 学习日记 第六天
    Python 学习日记 第五天
    Python 学习日记 第四天
    Redis 中的数据类型及基本操作
    Asp.net mvc 中View 的呈现(二)
    Asp.net mvc 中View的呈现(一)
    Asp.net mvc 中Action 方法的执行(三)
    Asp.net mvc 中Action 方法的执行(二)
    Asp.net mvc 中Action 方法的执行(一)
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5137146.html
Copyright © 2011-2022 走看看