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];

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

时间: 2017-10-08

IOS 中NSTimer定时器的使用

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

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

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

iOS 获取当前的ViewController的方法

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

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

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

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

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

IOS 中CATextLayer绘制文本字符串

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

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

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

浅谈iOS11新特性:新增拖拽交互体验

一.引言 在使用PC进行操作时,你一定遇到过这样的场景,可以将图片直接拖入聊天软件进行发送,可以将文档.音乐.视频文件等文件拖入相应应用程序直接进行使用.这种拖拽操作交互极大的方便了电脑的使用.在iOS11中,你可以在iPhone或iPad上构建这种交互体验! 说在前面的话: 拖拽操作在iPad上是支持跨应用程序的,你可以从一个应用中拖取项目,通过Home键回到主界面并且打开另一个应用程序,然后将被拖拽的项目传递给这个应用程序中.在iPhone上,拖拽操作只支持当前应用程序内,你可以将某个元素从

浅述python2与python3的简单区别

python2:print语句,语句就意味着可以直接跟要打印的东西,如果后面接的是一个元组对象,直接打印 python3:print函数,函数就以为这必须要加上括号才能调用,如果接元组对象,可以接收多个位置参数,并可以打印 1.表达式 在 Python 2 中为获得计算表达式,你会键入: X = raw_input ("enter some values) 但在 Python 3 中,你会键入: X = input ("enter some values") 因此,无论我们输

浅述节点的创建及常见功能的实现

新创建一个元素节点,并把该节点添加为文档中指定节点的子节点 1,新创建一个元素节点,返回值为指向元素节点的引用 var liNode =document.creatElement("li"); var cityNode=document.getElementById("city"); 新添加newChild子节点,该子节点将作为elementNode cityNode.appendChild(liNode); 2,创建一个文本节点 creatTextNode var

浅述SQL Server的语句类别 数据库范式 系统数据库组成

前言 终于等到这一天,我要开始重新系统学习数据库了,关于数据库这块,不出意外的话,每天会定时更新一篇且内容不会包含太多,简短的内容,深入的理解. SQL语句类别 SQL语句包括以下三个类别 (1)数据定义语言(Data Definnition Language)即DDL,我们数据最终从何而来,当然首先必须得建立表,所以它包括CREATE.ALTER.DROP表. (2)数据操作语言(Data Manipulation Language)即DML,我们对数据需要进行什么操作,当然无非就是增删改查,

浅述SQL Server的聚焦强制索引查询条件和Columnstore Index

前言 本节我们再来穿插讲讲索引知识,后续再讲数据类型中的日期类型,简短的内容,深入的理解. 强制索引查询条件 前面我们也讲了一点强制索引查询的知识,本节我们再来完整的讲述下 (1)SQL Server使用默认索引 USE TSQL2012 GO SELECT * FROM Sales.Orders 上述就不用我再啰嗦了,使用默认主键创建的聚集索引来执行查询执行计划. (2)SQL Server使用强制索引 USE TSQL2012 GO SELECT custid FROM Sales.Orde

浅述int与string类型转换的两种方法

具体详情如下所示: int -> String int i=12345; String s=""; 第一种方法:s=i+""; 第二种方法:s=String.valueOf(i); 这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢? String -> int s="12345"; int i; 第一种方法:i=Integer.parseInt(s); 第二种方法:i=Integer.valueOf(s).intV

浅述python中argsort()函数的实例用法

由于想使用python用训练好的caffemodel来对很多图片进行批处理分类,学习过程中,碰到了argsort函数,因此去查了相关文献,也自己在python环境下进行了测试,大概了解了其相关的用处,为了怕自己后面又忘了,就写下来权当加深理解了.(ps:我也是python小白,理解可能比较浅显) 1.先定义一个array数据 import numpy as np x=np.array([1,4,3,-1,6,9]) 2.现在我们可以看看argsort()函数的具体功能是什么: x.argsort

浅述Javascript的外部对象

Window 浏览器: - location:地址 - history:历史 - Document:文档 - screen:窗口 - navigator:帮助 > 1.外部对象就是浏览器提供的API -- **BOM** > 2.这些对象由w3c规定,由浏览器开发者设计并开发 > 3.这些对象分为2部分,其中BOM包含了DOM > 4.我们可以通过js访问这些对象 # 外部对象 > BOM (Browser Object Model) 浏览器对象模型,用来访问和操纵浏览器窗口

浅述python中深浅拷贝原理

前言 在c++中参数传递有两种形式:值传递和引用传递.这两种方式的区别我不在此说,自行补上,如果你不知道的话.我先上python代码,看完我们总结一下,代码如下: # copy module import import copy # number and string a = 12 a1 = a a2 = copy.copy(a) a3 = copy.deepcopy(a) # look addr print("==========number=======") print(id(a)