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

摘要:
3031}32#pragmamark-创建线程NSThread33-(void)touchesBegan:(UIEvent*)event34{35//[selfcreateThread1];@selector

一、基本使用

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

免责声明:文章转载自《iOS UI-线程(NSThread)及其安全隐患与通信》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Python3调用企业微信用于告警CSS3媒体查询总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# 单例模式(复习用)

单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。   一、经典模式: public class Singleton { private static Singleton instance; private Singleton()...

JS日历插件

一、简介 1. 注意事项 (1)My97DatePicker目录是一个整体,不可破坏里面的目录结构,也不可对里面的文件改名,可以改目录名; (2)各目录及文件的用途:         WdatePicker.js 配置文件,在调用的地方仅需使用该文件,可多个共存,以xx_WdatePicker.js方式命名         config.js 语言和皮肤配...

Java多线程 -yield用法

 前几天复习了一下多线程,发现有许多网上讲的都很抽象,所以,自己把网上的一些案例总结了一下!  一. Thread.yield( )方法:  使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。 ...

Windows几种线程同步方法介绍

系统中的所有线程都要访问系统资源,一个线程霸占某个资源,其他需要该资源的线程就不能完成自己的任务;另外如一个线程在读取某块内存中的数据,而另一个线程又正在修改这块内存的值,这同样不是我们想要的,所以线程之间必须要有一套自己的规则,不然就凌乱了。线程之间需要通信,如A线程霸占某个B线程需要的资源X,在A占用期间,B线程只能等待,或处于挂起状态,当A线程用完资...

VSCode 开发Vue 代码格式化setting.json设置

  { // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize "editor.tabSize": 2, // #每次保存的时候将代码按eslint格式进行修复 "eslint.autoFixO...

QString 和 TCHAR 的相互转换

参考资料: http://www.cnblogs.com/fuyanwen/p/3200536.htmlhttp://www.cnblogs.com/wendao/archive/2012/07/27/2612597.html 不能直接用: QString szqFileName = QString::fromLocal8Bit("data");const...