zoukankan      html  css  js  c++  java
  • iOS多线程的初步研究1

    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 (![[NSThreadcurrentThreadisCancelled])

        {

            // 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多线程
  • 相关阅读:
    yii2 gii 命令行自动生成控制器和模型
    控制器中的方法命名规范
    Vue Property or method "" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based
    IDEA插件:GsonFormat
    Spring Boot : Access denied for user ''@'localhost' (using password: NO)
    Typora添加主题
    Git基础命令图解
    Java Joda-Time 处理时间工具类(JDK1.7以上)
    Java日期工具类(基于JDK1.7版本)
    Oracle SQL Developer 连接Oracle出现【 状态: 失败 -测试失败: ORA-01017: invalid username/password; logon denied】
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3260892.html
Copyright © 2011-2022 走看看