iOS多线程的初步研究(一)

对于多线程的开发,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 (![[NSThreadcurrentThread] isCancelled])

    {

        // thread loop

        [NSThreadsleepForTimeInterval:1.0]; //等同于sleep(1.0);

    }

    // release resources of thread

}

这时如果调用[newThread cancel]; 就可以终止线程循环了。

NSThread有个类方法exit是用于立即结束当前线程的运行(有点鲁莽),因为无法保证当前线程对资源的释放,所以不推荐使用。

二、隐式调用

通过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; //在指定线程中执行,但该线程必须具备NSRunLoop。

- (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
标签: ios多线程

iOS多线程的初步研究1的更多相关文章

  1. iOS多线程的初步研究(六)

    iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...

  2. iOS多线程的初步研究3

    iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...

  3. iOS多线程的初步研究

    iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...

  4. iOS多线程的初步研究(一)-- NSThread

    对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...

  5. iOS多线程的初步研究(六)-- NSOperation

    iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...

  6. iOS多线程的初步研究(三)-- NSRunLoop

    弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...

  7. iOS多线程的初步研究(九)-- dispatch源

    dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...

  8. iOS多线程的初步研究(七)-- dispatch对象

    谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到.我们 ...

  9. iOS多线程的初步研究(五)-- 如何让NSURLConnection在子线程中运行

    可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行. 前面提到可以将NSTimer手动加 ...

随机推荐

  1. 多线程学习之一独木桥模式Single Threaded Execution Pattern

    Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...

  2. 给已经编译运行的Apache增加mod_proxy模块的配置方法

    在Linux系统下,需要给已经编译运行的Apache增加mod_proxy模块,可以按照如下方法配置. 具体配置步骤如下: 1. 首先定位到Apache源码的 proxy目录 # cd /root/s ...

  3. C语言库函数大全及应用实例十四

    原文:C语言库函数大全及应用实例十四                                       [编程资料]C语言库函数大全及应用实例十四 函数名: strset 功 能: 将一个串 ...

  4. 【Android平台安全方案】の #00-请不要在外部存储(SD卡)加密存储的敏感信息

    本文翻译自https://www.securecoding.cert.org/confluence/display/java/DRD00-J.+Do+not+store+sensitive+infor ...

  5. C# Winform 界面线程的Invoke死锁,以及Application.DoEvent的问题

    1.对于非界面线程来说,Invoke是把一个操作丢到界面线程的队列里,然后阻塞,等到这个操作被界面线程完成后,才继续后续操作.也就是说,Invoke是同步的. 问题来了,如果界面线程此时正在等待这个非 ...

  6. mongodb group包(最具体的、最受欢迎、最容易理解的解释)

    和数据库一样group经常常使用于统计.MongoDB的group还有非常多限制,如:返回结果集不能超过16M, group操作不会处理超过10000个唯一键.好像还不能利用索引[不非常确定]. Gr ...

  7. 学习的例子gcc+gdb+make

    1 小侃GCC 在正式使用gcc之前,我们先来侃侃gcc是啥玩意儿? 历史 如今的GCC是GNU Compiler Collection的简称.既然是Collection,就是指一些工具链的集合. 最 ...

  8. 初探Django线程发送邮件

    最近一直在纠结一个邮件发送的问题. 在本地Linux下搭建程序,不填写EMAIL设置就可以成功发送邮件,在远端的云服务器下的Linux环境就发送不了.在windows下搭建的程序也不能发送注册邮件,很 ...

  9. 分享UI设计模型

    UI设计模型是可重用的界面设计解决方案,可以让开发人员少走弯路,节约不少开发时间.下面慧都小编跟大家分享6个很有用的UI设计模型资源,希望对你有用: 1.UI Patterns 由一个丹麦人开发的UI ...

  10. TRIGGER的使用(修改SP自动触发)

    CREATE TRIGGER [trg_save_change_SP] ON DATABASE FOR CREATE_PROCEDURE, ALTER_PROCEDURE,DROP_PROCEDURE ...