zoukankan      html  css  js  c++  java
  • iOS多线程的初步研究(一)-- NSThread

    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 currentThreadisCancelled])

        {

            // 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方法。

  • 相关阅读:
    HDU 2852 KiKi's K-Number (主席树)
    HDU 2089 不要62
    Light oj 1140 How Many Zeroes?
    Bless You Autocorrect!
    HDU 6201 transaction transaction transaction
    HDU1561 The more ,The better (树形背包Dp)
    CodeForces 607B zuma
    POJ 1651 Mulitiplication Puzzle
    CSUOJ 1952 合并石子
    Uva 1599 Ideal path
  • 原文地址:https://www.cnblogs.com/desheng-Win/p/4700527.html
Copyright © 2011-2022 走看看