IOS开发教程第一季之03多线程day1--创建线程、桥接、线程状态、线程优先级、多线程操作共享资源,数据属性

1.创建线程

创建线程使用pthread_create

#import "ViewController.h"
#import <pthread/pthread.h>
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  //创建子线程
  //创建一个线程编号
   pthread_t pthread;//线程编号
   //第一个参数是线程编号,即线程编号的地址,
   //第二个参数是线程属性
   //第三个参数指向任何类型的指针,类似于id,但id是指向对象的,这里是c的类型指针,即第三个参数是一个线程要执行的函数
   //第四个参数 要执行的函数的参数
   //函数的返回值类型为int 0是成功,非零是失败
   int result=pthread_create(&pthread, NULL, demo, NULL);
   NSLog(@"touchsbegan %@",[NSThread currentThread]);
   if (result==0) {
     NSLog(@"线程创建成功");
   }else{
     NSLog(@"线程创建失败");
   }
}
//线程执行的函数(c的函数语法),这里需要返回一个地址,因为带*
void *demo(void *param){
  NSLog(@"hello world  %@",[NSThread currentThread]);
  return NULL;
}

@end

效果
2020-07-31 23:41:53.574612+0800 IOS107[6785:387304] touchsbegan <NSThread: 0x6000004b0f40>{number = 1, name = main}
2020-07-31 23:41:53.574751+0800 IOS107[6785:387304] 线程创建成功
2020-07-31 23:41:53.574733+0800 IOS107[6785:387478] hello world <NSThread: 0x6000004fc900>{number = 7, name = (null)}

2.创建线程带参及桥接(__bridge)
#import "ViewController.h"
#import <pthread/pthread.h>
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  //创建子线程
  //创建一个线程编号
   pthread_t pthread;//线程编号
   //第一个参数是线程编号,即线程编号的地址,
   //第二个参数是线程属性
   //第三个参数指向任何类型的指针,类似于id,但id是指向对象的,这里是c的类型指针,即第三个参数是一个线程要执行的函数
   //第四个参数 要执行的函数的参数
   //函数的返回值类型为int 0是成功,非零是失败
  
   //char *name="zhangsan";
  NSString* name=@"zhangsan";
  //把oc对象传递给c语言的函数,要桥接
   int result=pthread_create(&pthread, NULL, demo, (__bridge void *)name);
   NSLog(@"touchsbegan %@",[NSThread currentThread]);
   if (result==0) {
     NSLog(@"线程创建成功");
   }else{
     NSLog(@"线程创建失败");
   }
}
//线程执行的函数(c的函数语法),这里需要返回一个地址,因为带*
void *demo(void *param){
  //使用oc对象的时候也需要桥接一次
  NSString* name=(__bridge NSString*)(param);
  NSLog(@"hello world %@  %@",param,[NSThread currentThread]);
  return NULL;
}

@end

输出结果
2020-07-31 23:56:09.821820+0800 IOS107[6867:395884] touchsbegan <NSThread: 0x600001e9c7c0>{number = 1, name = main}
2020-07-31 23:56:09.821918+0800 IOS107[6867:395884] 线程创建成功
2020-07-31 23:56:09.822003+0800 IOS107[6867:396123] hello world zhangsan <NSThread: 0x600001ecd140>{number = 6, name = (null)}

3.NSSThread创建线程,方法1
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  //创建线程对象
  //第一个参数是第二个参数方法的对象
  //第二个参数是调用的方法
  //第三个参数是第二个调用方法的参数
  NSThread* thread= [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
  
  [thread start];
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  
}
-(void)demo{
  NSLog(@"hello %@",[NSThread currentThread]);
}

@end

效果:
2020-08-01 08:51:34.691124+0800 IOS107[934:29400] hello <NSThread: 0x600000ef04c0>{number = 7, name = (null)}

4.NSSThread创建线程,方法2
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  //分离新的线程,参数和上例类似
  [NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:nil];
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  
}
-(void)demo{
  NSLog(@"hello %@",[NSThread currentThread]);
}

@end

效果
2020-08-01 08:58:30.577407+0800 IOS107[970:33890] hello <NSThread: 0x600000fd6d00>{number = 7, name = (null)}

5.NSSThread创建线程,方法3,后台线程
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  //后台线程
  [self performSelectorInBackground:@selector(demo) withObject:nil];
 
}

-(void)demo{
  NSLog(@"hello %@",[NSThread currentThread]);
}

@end

效果
2020-08-01 09:10:41.063291+0800 IOS107[1009:40653] hello <NSThread: 0x6000039022c0>{number = 8, name = (null)}

6.NSSThread创建线程,方法4,创建线程是传入参数
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  //nsthread创建线程的基本方式
  NSThread* thread=[[NSThread alloc]initWithTarget:self selector:@selector(demo:) object:@"自定义的线程名称"];
  [thread start];
 
}

-(void)demo:(NSString *)name {
  NSLog(@"hello %@",name);
}

@end

效果:
2020-08-01 09:30:11.685584+0800 IOS107[1083:49676] hello 自定义的线程名称

7.线程状态1–就绪,阻塞与死亡
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  //新建线程对象
  NSThread* thread=[[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
  //线程进入就绪状态
  [thread start];
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  
}

-(void)demo{
  for (int i=0; i<20; i++) {
    NSLog(@"%d",i);
    if (i==5) {
      //阻塞状态
      [NSThread sleepForTimeInterval:4];//阻塞4秒钟
    }
    
    if (i==10) {
      //线程退出,进入死亡撞他
      [NSThread exit];
    }
  }
  
}

@end

结果
2020-08-01 09:43:00.861033+0800 IOS107[1180:57748] 0
2020-08-01 09:43:00.861109+0800 IOS107[1180:57748] 1
2020-08-01 09:43:00.861176+0800 IOS107[1180:57748] 2
2020-08-01 09:43:00.861253+0800 IOS107[1180:57748] 3
2020-08-01 09:43:00.861439+0800 IOS107[1180:57748] 4
2020-08-01 09:43:00.861518+0800 IOS107[1180:57748] 5
2020-08-01 09:43:04.864871+0800 IOS107[1180:57748] 6
2020-08-01 09:43:04.865174+0800 IOS107[1180:57748] 7
2020-08-01 09:43:04.865283+0800 IOS107[1180:57748] 8
2020-08-01 09:43:04.865367+0800 IOS107[1180:57748] 9
2020-08-01 09:43:04.865445+0800 IOS107[1180:57748] 10

8.线程状态2–优先级

thread1.threadPriority=10;//优先级数值越大,优先级越高

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
 
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  //新建线程对象
   NSThread* thread1=[[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
  //设定线程名字
  thread1.name=@"线程一";
  //指定线程的 优先级
  thread1.threadPriority=10;//优先级数值越大,优先级越高
  //线程进入就绪状态
   [thread1 start];
  //新建线程对象
  NSThread* thread2=[[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
  //线程进入就绪状态
  thread2.name=@"线程二";
  thread1.threadPriority=2;//优先级数值越大,优先级越高
  [thread2 start];
}

-(void)demo{
  for (int i=0; i<20; i++) {
    NSLog(@"%d --%@",i,[NSThread currentThread]);
    if ([NSThread isMainThread]) {
      int n=0;
      int m=5/n;
    }
    
    //[NSThread sleepForTimeInterval:2];
  }
  
}

@end
9.多线程操作共享资源(线程锁)
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,assign)int ticketCount;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.ticketCount=10;
 
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  //模拟买票窗口一
  NSThread* thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
  thread1.name=@"window1 for ticket";
  [thread1 start];
  //模拟买票窗口二
  NSThread* thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
  thread2.name=@"window2 for ticket";

  [thread2 start];
}

//模拟买票的方法
-(void)sellTickets{
  while(YES){
    //模拟耗时
    [NSThread sleepForTimeInterval:1];
    //添加线程锁
    @synchronized (self) {//线程同步
      if (self.ticketCount>0) {
        self.ticketCount--;
        NSLog(@"剩余票数为%d张票  %@",self.ticketCount,[NSThread currentThread]);
      }else{
        NSLog(@"票已经卖完了");
        break;
      }
    }
    
  }
  
}

@end

效果:
2020-08-01 11:32:22.401243+0800 IOS107[1582:104591] 剩余票数为9张票 <NSThread: 0x6000023fd0c0>{number = 8, name = window1 for ticket}
2020-08-01 11:32:22.401526+0800 IOS107[1582:104592] 剩余票数为8张票 <NSThread: 0x6000023fd040>{number = 9, name = window2 for ticket}
2020-08-01 11:32:23.404197+0800 IOS107[1582:104591] 剩余票数为7张票 <NSThread: 0x6000023fd0c0>{number = 8, name = window1 for ticket}
2020-08-01 11:32:23.404412+0800 IOS107[1582:104592] 剩余票数为6张票 <NSThread: 0x6000023fd040>{number = 9, name = window2 for ticket}
2020-08-01 11:32:24.405751+0800 IOS107[1582:104591] 剩余票数为5张票 <NSThread: 0x6000023fd0c0>{number = 8, name = window1 for ticket}
2020-08-01 11:32:24.405925+0800 IOS107[1582:104592] 剩余票数为4张票 <NSThread: 0x6000023fd040>{number = 9, name = window2 for ticket}
2020-08-01 11:32:25.410800+0800 IOS107[1582:104591] 剩余票数为3张票 <NSThread: 0x6000023fd0c0>{number = 8, name = window1 for ticket}
2020-08-01 11:32:25.411119+0800 IOS107[1582:104592] 剩余票数为2张票 <NSThread: 0x6000023fd040>{number = 9, name = window2 for ticket}
2020-08-01 11:32:26.412395+0800 IOS107[1582:104591] 剩余票数为1张票 <NSThread: 0x6000023fd0c0>{number = 8, name = window1 for ticket}
2020-08-01 11:32:26.415721+0800 IOS107[1582:104592] 剩余票数为0张票 <NSThread: 0x6000023fd040>{number = 9, name = window2 for ticket}
2020-08-01 11:32:27.415349+0800 IOS107[1582:104591] 票已经卖完了
2020-08-01 11:32:27.419348+0800 IOS107[1582:104592] 票已经卖完了
2020-08-01 11:33:35.305842+0800 IOS107[1582:105533] 票已经卖完了
2020-08-01 11:33:35.306078+0800 IOS107[1582:105532] 票已经卖完了
2020-08-01 11:33:36.123909+0800 IOS107[1582:105544] 票已经卖完了
2020-08-01 11:33:36.124134+0800 IOS107[1582:105545] 票已经卖完了

10.开启多线程异步下载网络图片
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,strong)UIScrollView* scrollView;
@property(nonatomic,strong)UIImageView* imageView;

@end

@implementation ViewController
//加载视图
-(void)loadView{
  self.scrollView=[[UIScrollView alloc]initWithFrame:[UIScreen mainScreen].bounds];
  self.scrollView.backgroundColor=[UIColor whiteColor];
  self.view=self.scrollView;
  
  self.imageView=[[UIImageView alloc]init];
  
  [self.scrollView addSubview:self.imageView];
}

- (void)viewDidLoad {
  [super viewDidLoad];
  
  //创建线程,注意,这里线程操作了UI主线程
  NSThread* thread=[[NSThread alloc]initWithTarget:self selector:@selector(downloadImage) object:nil];
  [thread start];
  [self downloadImage];
 
}


//下载网路图片的方法
-(void)downloadImage{
  //创建一个url地址
  NSURL* url=[NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1596266796912&di=2b160825f46fe50a328bba978e6d385c&imgtype=0&src=http%3A%2F%2F01.minipic.eastday.com%2F20170421%2F20170421143734_ba2eace48dd7194f8c64d545ad7c50ca_8.jpeg"];
  //下载图片
  NSData* data=[NSData dataWithContentsOfURL:url];
  //二进制数据转化为图片
  UIImage* image=[UIImage imageWithData:data];
  //操作了UI主线程,一定要去主线程上更新UI控件。线程间通信
  //第三个参数waitUntilDone值是YES会等待方法执行完毕,才会执行后续代码
  [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
  
}
//更新UI操作界面
-(void)updateUI:(UIImage*)image{
  //将图片添加到self.imageview上
  self.imageView.image=image;
  //让imageview和内容大小保持一致
  [self.imageView
   sizeToFit ];
  //让scrollview滚动起来
  self.scrollView.contentSize=image.size;
}

@end

效果:
在这里插入图片描述

11.关于属性

属性包括:
retain
strong
weak
assign分配
copy


字符串一般是用 copy
block作为属性的时候使用 copy
delegate用weak修饰
bool,数值等使用assign
arc下才能用weak
mrc下使用retain
拖线一般使用weak

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值