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 == ) {
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 = ; i <; i++) { if (i == ) {
//阻塞状态
//让当前的线程睡一段时间
[NSThread sleepForTimeInterval:];
}else if (i == )
{
//死亡状态
[NSThread exit];
}
NSLog(@"%d",i);
}
}

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

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//线程属性
//主线程占用的内存空间
NSLog(@"%zd",[NSThread currentThread].stackSize/);
//创建线程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/);
// NSLog(@"%@",[NSThread currentThread]);
for (int i = ; i < ; 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 = ; }
- (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 > ) {
self.totalTickets = self.totalTickets - ;
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:];
self.HMImageView.image = img;
}

1.多线程-NSThread的更多相关文章

  1. iOS多线程 NSThread/GCD/NSOperationQueue

    无论是GCD,NSOperationQueue或是NSThread, 都没有线程安全 在需要同步的时候需要使用NSLock或者它的子类进行加锁同步 "] UTF8String], DISPA ...

  2. 多线程NSThread基本用法

        #import "ViewController.h" @interface ViewController () @end @implementation ViewContr ...

  3. [iOS]深入浅出 iOS 之多线程 NSThread

    OS 支持多个层次的多线程 编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法.     下面简要说明这三种不同范式:  Thread 是这三种范式里面相对轻量级的,但也是使用起 ...

  4. 多线程 -- NSThread

    NSThread NSThread 一个NSThread对象就代表一条线程 创建线程的几种方式 alloc/init // 1.创建线程 NJThread *thread = [[NJThread a ...

  5. [iOS 多线程 & 网络 - 1.1] - 多线程NSThread

    A.NSThread的基本使用 1.创建和启动线程 一个NSThread对象就代表一条线程创建.启动线程NSThread *thread = [[NSThread alloc] initWithTar ...

  6. 多线程 NSThread GCD

    ios多线程实现种类 NSThread NSOperationQueue NSObject GCD *************** 1.NSThread //线程 第一种 NSThread *thre ...

  7. iOS多线程NSThread和GCD

    在iOS中啊  其实有多种方法实现多线程 这里只记录两个比较常用的  或者说我比较常用的 一个就是BSThread 另一个就是一听名字就比较霸气的妇孺皆知的GCD 先说一下NSThread吧 这个方式 ...

  8. iOS 多线程NSThread理解与场景示例

    NSThread是相对GCD和NSOperationQuene而言,比较轻量级的一种多线程处理方式. 但同时,它的弊端就是需要自己管理线程的生命周期,以及线程同步:而另外两种不需要自己管理. 常见方法 ...

  9. 九、使用多线程——NSThread,GCD和NSOperation

    概述 早上起床,你先打开洗衣机,然后用热水把泡面泡上,接着打开电脑开启一天的码农生活.其中“洗衣服”.“泡泡面”和“码代码”3个任务(线程)同时进行,这就是多线程.网上有许多关于多线程的经典解释,此处 ...

  10. IOS 多线程 NSThread

    一个正在运行的应用程序是一个进程,一个进程会默认开启一个主线程,但是在主线程中的操作是串行的,也就是当有多个任务同时需要完成的时候,是按照顺序一个个执行.因此,为了提高效率,会在进程中开启多个线程,每 ...

随机推荐

  1. Servlet和Struts2同时使用

    在做WEB项目时,要么是Struts+Spring+Hibernate,要是就直接使用servlet.这次碰到一个项目,经理想要把之前一个用servlet做的部分模块移植到当前项目下(Struts+S ...

  2. javascript面向对象(三):非构造函数的继承

    本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...

  3. ps工具箱总结

    1.矩形工具 四个属性 1.选区2.重叠选区3.减去选区4.区域化缩小选区 样式:固定比例 固定大小 正常 //前两项可以设置宽高 3.快速选择工具.魔棒工具 快速选择工具: 三个属性 1.选区2.增 ...

  4. EMF学习,为了实现可扩展可自定义的模型验证 - emf quary 与 OCL

    http://blog.csdn.net/javaman_chen/article/details/6020050 //这里的验证强调的是condition的构造,基于查找来判断验证结果.支持OCL也 ...

  5. 查找Maven JAR坐标

    http://mvnrepository.com/ http://search.maven.org/

  6. JMeter 将上一个请求的结果作为下一个请求的参数——使用正则提取器(转载)

    在接口测试和压力测试过程中,经常会将几个流程串联起来才能测试.如:我要进行获取用户信息接口测试,我就要先登录成功后,才能获取用户信息.所以,我就要首先要登录,获得我的登录凭证(tokenId或tick ...

  7. HTML 播放器 写给自己

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  8. URL转Drawable之 Android中获取网络图片的三种方法

    转载自: http://doinone.iteye.com/blog/1074283 Android中获取网络图片是一件耗时的操作,如果直接获取有可能会出现应用程序无响应(ANR:Applicatio ...

  9. QQ五笔词库转拼音词库小工具

    参考文章<用QQ拼音打五笔>中提供的信息而制作的小工具,功能是将QQ五笔导出词库文件转换为QQ拼音自定义短语使用的.ini格式文件,这样就可以使用QQ拼音进行五笔拼音混输了. 混输效果不错 ...

  10. Quartz2D 编程指南(二)变换、图案、阴影

    概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 5.变换 简介 Quartz 2D ...