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

来源:互联网 发布:菠萝饭软件 编辑:程序博客网 时间:2024/05/17 05:00

目录[-]

  • iOS多线程的初步研究(一)
  • 一、显式调用
  • 二、隐式调用
  • 通过NSObject的Category方法调用:
  • 三、NSThread的其它一些常用的方法
  • 四、一些非线程调用(NSObject的Category方法)
  • 五、线程执行顺序
  • iOS多线程的初步研究(一)

    ===

    来源: http://www.cnblogs.com/sunfrog/p/3243230.html

    NSThread 

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

    一、显式调用

    • 显示调用的类为NSThread。一般构造NSThread的线程对象可通过两种方式:

      • 初始化线程主方法:1.类方法.2.实例方法可以拿到线程对象,便于以后终止线程。

      • [NSThread detachNewThreadSelector:@selector(run:) toTarget:target withObject:obj];

      • NSThread *newThread = [[NSThread alloc] initWithTarget:target selector:@selector(run:) object:obj];

    • 定义NSThread的子类MyThread,然后实现main方法(即方法1中的run)。然后创建新对象:

      • MyThread *newThread = [[MyThread alloc] init];

      • 启动线程:[newThread start];

      • 终止线程:实际上没有真正提供终止线程的api,但有个方法可以方便地利用cancel方法; 它是改变线程运行的一个状态标志,我们可以这样来利用:

    在main方法中这样实现线程循环

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    - (void)main
     
    {
     
    // 得到当前运行线程
     
    while(![[NSThread currentThread] isCancelled])
     
    {
     
        // thread loop
     
        [NSThread sleepForTimeInterval:1.0];//等同于sleep(1);
        [newThread cancel]
     
    }
     
    // release resources of thread
     
    }
    1. 这时如果调用[newThread cancel]; 就可以终止线程循环了。

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


    二、隐式调用

    通过NSObject的Category方法调用:

    1.在主线程中运行方法,wait表示是否阻塞这个方法的调用,如果为YES则等待主线程中运行方法结束。一般可用于在子线程中调用UI方法。

    • (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

      2.在指定线程中执行,但该线程必须具备run loop

    • (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

    3.隐含产生新线程。

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

    1. 子线程中回调UI线程来更新UI

      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      - (void)loadData
       
      {
       
      //从网络中获取数据响应
       
      //更新数据
       
       //回调主线程(即系UI线程)
       
       //uiObj 可以是TableView或者其他UI类
       
      [uiObj performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
       
      }

    ·也可以使用NSThread实现同样的功能,loadData相当于NSThread的main方法。·

    0 0
    原创粉丝点击