iOS-多线程之NSThread

在iOS开发中,为了合理利用CPU的多核,提高程序的执行效率 和 用户体验,我们需要使用多线程。

iOS中常用的多线程技术有:NSThread,GCD,NSOperation
1 NSThread:OC语言,面向对象,简单易用,可直接操作线程对象;
2 GCD:C语言,旨在替代NSThread,充分利用了CPU的多核,不需要考虑线程的生命周期;
3 NSOperation:OC语言,面向对象,基于GCD(底层是GCD),比GCD更加简单实用,也不需要考虑线程的生命周期。

首先研究下 NSThread
    // 创建线程 01(通过创建线程对象创建线程) 
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(eat:) object:@"apple"];
    // 为线程明名
    thread.name = @"eat-thread";
    // 启动线程
    [thread start];

    注:一个NSThread对象就代表一条线程
    // 创建线程 02(隐式创建并启动线程)
[self performSelectorInBackground:@selector(eat:) withObject:@"apple"];
    // 创建线程 03 (类方法创建线程)
[NSThread detachNewThreadSelector:@selector(eat:) toTarget:self withObject:@"apple"];
- (void)eat:(NSString *)food {
     NSLog(@"eat---%@---%@", food, [NSThread currentThread]);
}
// 让线程睡眠n秒(阻塞n秒)
[NSThread sleepForTimeInterval:n]; 
// 让线程睡眠到某一时刻,苏醒后继续执行
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
// 直接退出线程
[NSThread exit]; 

线程之间的通信
1、什么叫做线程间通信?

在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信

2、线程间通信的体现

01: 一个线程传递数据给另一个线程
02 : 在一个线程中执行完特定任务后,转到另一个线程继续执行任务

线程间通信常用方法
// option 1
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// option 2
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

线程通信事例(利用子线程下载图片,回到主线程显示图片)

    // 创建一个子线程,用来下载图片 
    [self performSelectorInBackground:@selector(downloadImage) withObject:nil];

    // downloadImage function
    - (void)downloadImage {
    // 图片的网络路径
    NSURL *url = [NSURL URLWithString:@"http://xxx.jpg"];
    // 加载图片,并转为二进制文件(此方法耗内存和时间)
    NSData *data = [NSData dataWithContentsOfURL:url];
    // 生成图片
    UIImage *image = [UIImage imageWithData:data];

    // 回到主线程,显示图片 (与UI有关的操作,请放主线程)
    // option-1
    [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
    // option-2
    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    // option-3
    [self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];

}
// 设置图片的方法
-(void)showImage:(UIImage *)image {
      self.imageView.image = image;
}
主线程相关用法
    + (NSThread *)mainThread; // 获得主线程
    - (BOOL)isMainThread;     // 是否为主线程
    + (BOOL)isMainThread;     // 是否为主线程

线程安全 — 资源抢夺

一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
“比如多个线程访问同一个对象、同一个变量、同一个文件”
当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题

解决方案:使用互斥锁

互斥锁的使用前提:多条线程抢夺同一块资源

互斥锁使用格式
    @synchronized(锁对象) { 
    // 需要锁定的代码  
    }

优点:能有效防止因多线程抢夺资源造成的数据安全问题

缺点:需要消耗大量的CPU资源

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值