iOS多线程的初步研究(一)-- NSThread
对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用。产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用。
一、显示调用的类为NSThread。一般构造NSThread的线程对象可通过两种方式:
1. 初始化线程主方法:
[NSThread detachNewThreadSelector:@selector(run:) toTarget:target withObject:obj];//类方法
或
NSThread *newThread = [[NSThread alloc] initWithTarget:target selector:@selector(run:) object:obj]; //实例方法可以拿到线程对象,便于以后终止线程。
2. 定义NSThread的子类MyThread,然后实现main方法(即方法1中的run)。然后创建新对象:
MyThread *newThread = [[MyThread alloc] init];
启动线程:[newThread start];
终止线程:实际上没有真正提供终止线程的api,但有个cancel方法可以利用; 它改变线程运行的一个状态标志,我们可以这样来利用:
先在run:或main方法中这样实现线程循环:
- (void)main
{
// thread init
while (![[NSThread currentThread] isCancelled])
{
// thread loop
[NSThread sleepForTimeInterval:1.0]; //等同于sleep(1);
}
// release resources of thread
}
这时如果调用[newThread cancel]; 就可以终止线程循环了。
NSThread有个类方法exit是用于立即结束当前线程的运行(不安全),因为无法保证当前线程对资源的释放,所以不推荐使用。像java中Thread的stop方法也被弃用一样,因为不安全。
二、隐式调用
通过NSObject的Category方法调用,罗列如下:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; //在主线程中运行方法,wait表示是否阻塞这个方法的调用,如果为YES则等待主线程中运行方法结束。一般可用于在子线程中调用UI方法。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait; //在指定线程中执行,但该线程必须具备run loop。
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg; //隐含产生新线程。
三、NSThread的其它一些常用的方法
创建的线程是非关联线程(detached thread),即父线程和子线程没有执行依赖关系,父线程结束并不意味子线程结束。
1. + (NSThread *)currentThread; //获得当前线程
2. + (void)sleepForTimeInterval:(NSTimeInterval)ti; //线程休眠
3. + (NSThread *)mainThread; //主线程,亦即UI线程了
4. - (BOOL)isMainThread; + (BOOL)isMainThread; //当前线程是否主线程
5. - (BOOL)isExecuting; //线程是否正在运行
6. - (BOOL)isFinished; //线程是否已结束
四、一些非线程调用(NSObject的Category方法)
即在当前线程执行,注意它们会阻塞当前线程(包括UI线程):
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
以下调用在当前线程延迟执行,如果当前线程没有显式使用NSRunLoop或已退出就无法执行了,需要注意这点:
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
而且它们可以被终止:
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;
五、线程执行顺序
通常UI需要显示网络数据时,可以简单地利用线程的执行顺序,避免显式的线程同步:
1. UI线程调用
[threadObj performSelectorInBackground:@selector(loadData) withObject:nil];
2. 子线程中回调UI线程来更新UI
- (void)loadData
{
//query data from network
//update data model
//callback UI thread
[uiObj performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
}
也可以使用NSThread实现同样的功能,loadData相当于NSThread的main方法。
iOS多线程的初步研究(一)-- NSThread的更多相关文章
- iOS多线程的初步研究(六)
		
iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...
 - iOS多线程的初步研究3
		
iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...
 - iOS多线程的初步研究1
		
iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...
 - iOS多线程的初步研究
		
iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...
 - iOS多线程的初步研究(六)-- NSOperation
		
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...
 - iOS多线程的初步研究(三)-- NSRunLoop
		
弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...
 - iOS多线程的初步研究(九)-- dispatch源
		
dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...
 - iOS多线程的初步研究(七)-- dispatch对象
		
谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到.我们 ...
 - iOS多线程的初步研究(五)-- 如何让NSURLConnection在子线程中运行
		
可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行. 前面提到可以将NSTimer手动加 ...
 
随机推荐
- SpringBoot 整合 Jpa
			
项目目录结构 pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...
 - [转]提示错误 package javax.servlet.jsp does not exist package javax.servletr.jsp.tagext does not exist
			
你在JAVA servlet容器运行的时候没配置servlet-api.jar,tools.jar,rt.jar,jsp-api.jar的classpath 我的classpath= .;%JAVA_ ...
 - Android测试之Keycode
			
问题: 昨天做测试Case,发现一个网游APK运行界面,uiautomator无法捕捉获取. 因而输入的时候只得运用(dut.onclick(int a, int y))坐标点击的方法来输入用户名和密 ...
 - Web安全开发指南--异常错误处理与日志审计
			
1.异常错误处理与日志审计 5.1.日志审计系统安全规则 1 日志系统能够记录特定事件的执行结果(比如 成功或失败). 确保日志系统包含如下重要日志信息: 1. 日志发生的时间: 2. 事件的严重 ...
 - ERDAS遥感图像配准、及其它一些基本处理
			
内容中包含 base64string 图片造成字符过多,拒绝显示
 - 四种有能力取代Cookies的客户端Web存储方案
			
目前在用户的网络浏览器中保存大量数据需要遵循几大现有标准,每一种标准都拥有自己的优势.短板.独特的W3C标准化状态以及浏览器支持级别.但无论如何,这些标准的实际表现都优于广泛存在的cookies机制. ...
 - 18 个最佳代码编辑器/IDE推荐
			
本文为开发人员收录了18个最好的代码编辑器/IDE工具,希望你会喜欢. 1) chocolatapp Chocolat是最新出现的一款强大的Mac系统文本编辑器,兼具原生的Cocoa及强大的文本编辑功 ...
 - Signavio
			
Signavio web建模器 从version 4.1开始,jBPM绑定了一个完全开源的基于web的BPM设计器工具 叫做'Signavio'.这个Signavio web建模器是和JBoss jB ...
 - iview2.x版本升级3.x版本icon修改清单
			
当前公司使用有一个旧项目的前端组件库是iview2.x,入职以来维护该项目过程中碰到2.x版本无数的坑. 最近需求不多,闲来无事把2.x升级到3.x版本了. 新版本除了网上轻易可查到的button组件 ...
 - JVM调优思路
			
一.jvm内存调优 (Gc 和 Full gc) hotspot -Xms40m 最小堆内存 -Xmx512m 最大值内存 -verboose:gc -XX:PrintGCDetails -XX: ...