ios多线程初步研究
2015-11-12 14:44
323 查看
对于多线程的开发,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_ NSUserDefaults_数据本地化的轻型装备
- iOS 键盘自适应(IQKeyboardManager)使用小结
- iOS 开始
- iOS9的一些适配
- iOS9的一些适配
- iOS PCH文件
- iOS使用推送流程
- iOS, ViewControl的生命周期
- iOS中三种数据存储(本地持久化),cell是手写创建和stroyboard或者xib创建的初始化的方法
- IOS四种保存文件的方式
- iOS中tableView的三种刷新方法
- iOS中Quartz2D
- iOS工程路径,路径宏
- iOS中Main函数作用,xcode7数据显示,自己设置主窗口
- IOS 开发,调用打电话,发短信,打开网址
- iOS中unicode 转汉字
- iOS开发 - 控制在生命周期内只运行一次
- ios 高斯模糊
- IOS代码混淆
- iOS学习之关于#import导入补全问题