IOS多线程编程NSThread的使用方法

IOS多线程编程NSThread的使用方法

NSThread是多线程的一种,有两种方法创建子线程

(1)优点:NSThread 比GCD、NSOperation都轻量级

(2)缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销

第一种是隐藏创建,有以下几种方式:

(1)多用于串行:- (id)performSelector:(SEL)aSelector withObject:(id)object;
(2)后台执行,多用于并行:- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg;
(3)延迟执行:- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
(4)回到主线程执行:- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
注意:
(1)通过方法" + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument; ",或"+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget"停止执行;

示例:

//创建子线程-隐式方法

// 子线程-串行
[self performSelector:@selector(showCount:) withObject:@(11)];
[self performSelector:@selector(showCount:) withObject:@(12)];
[self performSelector:@selector(showCount:) withObject:@(23)];
// 子线程-并行(后台) 
[self performSelectorInBackground:@selector(showCount:) withObject:@(41)];
[self performSelectorInBackground:@selector(showCount:) withObject:@(42)];
// 回到主线程
[self performSelectorOnMainThread:@selector(showCount:) withObject:@(51) waitUntilDone:YES];
// 子线程延迟执行
[self performSelector:@selector(showCount:) withObject:@(61) afterDelay:5.0];
// 停止
[NSObject cancelPreviousPerformRequestsWithTarget:self]; 

第二种是显示创建,方式如下:

 - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument;

注意:

(1)通过方法" - (void)start; "开始执行;
 (2)通过方法" - (void)cancel; "停止执行;

示例:

//创建子线程-显示方法

self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(showCount:) object:@(61)];
self.thread.name = @"计数";
[self.thread start];
[self.thread cancel];

代码示例

- (void)showCount:(NSNumber *)number
{
 NSInteger count = arc4random() % 1000;
 count = 1000;
 for (int i = 0; i < count; i++)
 {
  NSLog(@"第 %@ 个 i = %@", number, @(i)); 

  // 休眠n秒再执行
  [NSThread sleepForTimeInterval:0.2]; 

  // 停止
//  BOOL isStop = [self.thread isCancelled];
//  if (isStop)
//  {
//   NSLog(@"2 停止");
//   break;
//  }
  if (isCancelThread)
  {
   NSLog(@"2 停止");
   break;
  }
 }
}
bool isCancelThread = NO;
- (void)stopClick
{
 [NSObject cancelPreviousPerformRequestsWithTarget:self]; 

 if (self.thread)
 {
  BOOL isExecuting = [self.thread isExecuting];
  if (isExecuting)
  {
   NSLog(@"1 停止");
//   [self.thread cancel];
   isCancelThread = YES;
  }
 }
}
- (void)downloadImage:(NSString *)imageUrl
{
 NSURL *url = [NSURL URLWithString:imageUrl];
 NSData *data = [[NSData alloc] initWithContentsOfURL:url];
 UIImage *image = [[UIImage alloc] initWithData:data];
 if (image == nil)
 { 

 }
 else
 {
//  [self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:YES];
  [self performSelectorInBackground:@selector(updateImage:) withObject:image];
 } 

// NSURL *url = [NSURL URLWithString:imageUrl];
// NSURLRequest *request = [NSURLRequest requestWithURL:url];
// NSURLSession *session = [NSURLSession sharedSession];
// NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
//
//  // 输出返回的状态码,请求成功的话为200
//  NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
//  NSInteger responseStatusCode = [httpResponse statusCode];
//  NSLog(@"%ld", responseStatusCode);
//
//  UIImage *image = [UIImage imageWithData:data];
////  [self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:YES];
//  [self performSelectorInBackground:@selector(updateImage:) withObject:image];
// }];
//
// // 使用resume方法启动任务
// [dataTask resume];
}
- (void)updateImage:(UIImage *)image
{
 self.imageview.image = image; 

// self.imageview = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 10.0, (CGRectGetWidth(self.view.bounds) - 10.0 * 2), (CGRectGetWidth(self.view.bounds) - 10.0 * 2))];
// [self.view addSubview:self.imageview];
// self.imageview.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.2];
//
// self.imageview.image = image;
}
NSString *imageUrl = @"http://ww1.sinaimg.cn/crop.0.0.1242.1242.1024/763fb12bjw8empveq3eq8j20yi0yiwhw.jpg";
// 隐藏创建
// [self performSelectorInBackground:@selector(downloadImage:) withObject:imageUrl];
[self performSelectorOnMainThread:@selector(downloadImage:) withObject:imageUrl waitUntilDone:YES];
// 创建子线程-显示方法
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:imageUrl];
self.thread.name = @"imageDownload";
[self.thread start];

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • IOS 中CATextLayer绘制文本字符串

    IOS 中CATextLayer绘制文本字符串 CATextLayer使用Core Text进行绘制,渲染速度比使用Web Kit的UILable快很多.而且UILable主要是管理内容,而CATextLayer则是绘制内容. CATextLayer的绘制文本字符串的效果如下: 代码示例: // 绘制文本的图层 CATextLayer *layerText = [[CATextLayer alloc] init]; // 背景颜色 layerText.backgroundColor = [UIC

  • iOS 获取当前的ViewController的方法

    本文介绍了iOS 获取当前的ViewController,分享给大家.具体如下 通过简单的判断[UIViewController class],就认定它是想要的控制器是不对的: if ([nextResponder isKindOfClass:[UIViewController class]]) { result = nextResponder; }else { result = window.rootViewController; } 因为:isKindOfClass:确定一个对象是否是一个类

  • IOS 中NSTimer定时器的使用

    IOS 中NSTimer定时器的使用 NSTimery 定时器,主要用于进行定时执行指定方法,常用场景如:获取验证码的按钮倒计时:图片轮播定时. 1 使用注意事项: 1.1 倒计时时间间隔(时间单位是秒) 1.2 指定的执行方法 1.3 实现指定执行方法的对象 1.4 是否重复执行 2 对象的内存管理及销毁 2.1 使用方法" invalidate "进行停止 2.2 将对象设置为" nil " 2.3 特别是在返回到其他视图控制器的时候,要在方法" -

  • IOS 开发之查看大图的实现代码

    IOS 开发之查看大图的实现代码 本项目是取自传智播客的教学项目,加入笔者的修改和润饰. 1. 项目名称:查看大图 2. 项目截图展示 3. 项目功能 左右滑动查看图片 支持缩放功能 点击中间按钮移动图片 4. 项目代码 #import "ViewController.h" @interface ViewController ()<UIScrollViewDelegate> @property (strong, nonatomic) IBOutlet UIScrollVie

  • iOS中常见的视图和图片处理示例详解

    前言 众所周知在开发中不可避免的会遇到一些图片和视图的处理,我这里总结的这些只是我遇到的一些,以供下次使用查看.下面话不多说了,来一起看看详细的介绍吧. 图片的旋转 是UIImage的扩展类,直接使用UIImage的对象调用即可 UIImage #import <QuartzCore/QuartzCore.h> #import <Accelerate/Accelerate.h> @implementation UIImage (ImageRotate) -(UIImage *)im

  • IOS初始化控制器的实现方法总结

    IOS初始化控制器的实现方法总结 一.ViewControllViewController方法 #import "AppDelegate.h" #import "ViewController.h" @interface AppDelegate () @property(nonatomic,strong) ViewController *viewController; @end @implementation AppDelegate - (BOOL)applicati

  • 浅述iOS11 Xcode 9 按住command 单击 恢复到从前(直接跳转到定义)

    2017年9月20日,苹果如期推送 Xcode 9 和 iOS 11的更新. Xcode 9正式版与之前beta版本相差不大,编辑器有较大调整,试写代码,发现"跳转定义"跟以前不一样了,之前按住command +鼠标左键即可跳转定义. 如今不一样了,如图: 首先整块区域高亮,弹出菜单,Jump to Definition在菜单第一项,点击才会跳转,我想大部分人都不喜欢这种操作,多了一步,实在讨厌,如果你想找回之前的快速跳转定义的姿势,那么恭喜你看到了我: 鼠标用户: 对准你的对象,Co

  • IOS多线程编程NSThread的使用方法

    IOS多线程编程NSThread的使用方法 NSThread是多线程的一种,有两种方法创建子线程 (1)优点:NSThread 比GCD.NSOperation都轻量级 (2)缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 第一种是隐藏创建,有以下几种方式: (1)多用于串行:- (id)performSelector:(SEL)aSelector withObject:(id)object; (2)后台执行,多用于并行:- (void)performSele

  • Java多线程编程安全退出线程方法介绍

    线程停止 Thread提供了一个stop()方法,但是stop()方法是一个被废弃的方法.为什么stop()方法被废弃而不被使用呢?原因是stop()方法太过于暴力,会强行把执行一半的线程终止.这样会就不会保证线程的资源正确释放,通常是没有给与线程完成资源释放工作的机会,因此会导致程序工作在不确定的状态下 那我们该使用什么来停止线程呢 Thread.interrupt(),我们可以用他来停止线程,他是安全的,可是使用他的时候并不会真的停止了线程,只是会给线程打上了一个记号,至于这个记号有什么用呢

  • IOS多线程编程的3种实现方法

    前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要阻塞主线程. iOS中有以下3种多线程编程方法: NSThread Grand Centeral Dispatch(GCD) NSOperation和NSOperationQueue 1.NSThread 这是最轻量级的多线程的方法,使用起来最直观的多线程编程方法.但是因为需要自己管理线程的生命周期,线程同步.经常使用NSThread进行调试,在实际项目中不推荐使用. //

  • iOS多线程开发——NSThread浅析

    在iOS开发中,多线程的实现方式主要有三种,NSThread.NSOperation和GCD,我前面博客中对NSOperation和GCD有了较为详细的实现,为了学习的完整性,今天我们主要从代码层面来实现NSThread的使用.案例代码上传至 https://github.com/chenyufeng1991/NSThread. (1)初始化并启动一个线程 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated

  • 在IOS中为什么使用多线程及多线程实现的三种方法

    多线程是一个比较轻量级的方法来实现单个应用程序内多个代码执行路径. 在系统级别内,程序并排执行,程序分配到每个程序的执行时间是基于该程序的所需时间和其他程序的所需时间来决定的. 然而,在每个程序内部,存在一个或者多个执行线程,它同时或在一个几乎同时发生的方式里执行不同的任务. 概要提示: iPhone中的线程应用并不是无节制的,官方给出的资料显示,iPhone OS下的主线程的堆栈大小是1M,第二个线程开始就是512KB,并且该值不能通过编译器开关或线程API函数来更改,只有主线程有直接修改UI

  • Linux下的多线程编程实例解析

    1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程.现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux. 为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它

  • iOS多线程应用开发中使用NSOperation类的基本方法

    一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会⾃动将NSOperationQueue中的NSOperation取出来 (4)将取出的NSOperati

  • C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法

    本文实例讲述了C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法.分享给大家供大家参考,具体如下: 摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景.该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据. 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的

  • nodejs中使用多线程编程的方法实例

    在以前的博文别说不可能,nodejs中实现sleep中,我向大家介绍了nodejs addon的用法.今天的主题还是addon,继续挖掘c/c++的能力,弥补nodejs的弱点. 我曾多次提到过nodejs的性能问题.其实就语言本身而言,nodejs的性能还是很高的,虽然不及大多部静态语言,但差距也并不大:相对其他动态语言而言,速度优势非常明显.但为什么我们常常说nodejs不能胜任CPU密集型场景呢?因为由于其单线程特性,对于CPU密集型场景,它并不能充分利用CPU.计算机科学中有一个著名的A

  • 实例总结Java多线程编程的方法

    1.什么时候使用多线程编程 一个任务在正常情况下是按顺序执行的,但是如果当前任务里有多个相似进程块(例如for,while语句),我们就可以考虑把这些代码块抽出来并行运行,无需阻塞 2.实现多线程的几种方式 一种是继承Thread类重写run方法,另一种是实现Runnable接口重写run方法 启动多线程很多情况下是为了处理并发进程,此时对于部分实时性要求不是那么高的业务需求,我们还可以通过实现队列的方式,异步实现. 3.举例 继承Thread /** * * @ClassName: Threa

随机推荐