美文网首页iOS开发
iOS开发-使用Runloop实现线程保活、线程常驻

iOS开发-使用Runloop实现线程保活、线程常驻

作者: Pandakingli | 来源:发表于2017-11-07 18:02 被阅读20次

保证线程的长时间存活
在iOS开发过程中,有时一些花费时间比较长的操作阻塞主线程,导致界面卡顿,那么我们就会创建一个子线程,然后把这些花费时间比较长的操作放在子线程中来处理。可是当子线程中的任务执行完毕后,子线程就会被销毁掉。

首先,我们创建一个testThread类,继承自NSThread,然后重写dealloc 方法。


@interface testThread : NSThread

@end

@implementation testThread
- (void)dealloc
{
    NSLog(@"%s",__func__);
}
@end
- (void)viewDidLoad 
{
    [super viewDidLoad];
    // 测试线程
    [self threadTest];
}

- (void)threadTest
{
    testThread *subThread = [[testThread alloc] initWithTarget:self selector:@selector(subThreadAction) object:nil];
    [subThread start];
}

- (void)subThreadAction
{
    @autoreleasepool {

        NSLog(@"%@----子线程任务开始",[NSThread currentThread]);
        [NSThread sleepForTimeInterval:2.0];
        NSLog(@"%@----子线程任务结束",[NSThread currentThread]);

    }

}

当子线程中的任务执行完毕后,线程就被立刻销毁了。
如果程序中,需要经常在子线程中执行任务,频繁的创建和销毁线程,会造成资源的浪费。
这时候我们就可以使用RunLoop来让该线程长时间存活而不被销毁。

#import "SubViewController.h"
#import "testThread.h"

@interface SubViewController ()
@property(nonatomic,strong) testThread* ttThread;
@end

@implementation SubViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // 测试线程
    [self threadTest];

}


- (void)threadTest
{
    testThread *subThread = [[testThread alloc] initWithTarget:self selector:@selector(subThreadEnter) object:nil];

    [subThread setName:@"测试线程"];
    [subThread start];

    self.ttThread = subThread;
    
}

/**
 子线程任务
 */
- (void)subThreadAction
{
    NSLog(@"启动RunLoop后--%@",[NSRunLoop currentRunLoop].currentMode);
    NSLog(@"%@----子线程任务开始",[NSThread currentThread]);
   
    
    for (int i=0; i<300; i++)
    {
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"----子线程任务 %ld",(long)i);
    }
    NSLog(@"%@----子线程任务结束",[NSThread currentThread]);
}

/**
 子线程启动后,启动runloop
 */
- (void)subThreadEnter
{
    @autoreleasepool {
        
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        
        //如果注释了下面这一行,子线程中的任务并不能正常执行
        [runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes];
        
        NSLog(@"启动RunLoop前--%@",runLoop.currentMode);
        [runLoop run];
        
    }
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self performSelector:@selector(subThreadAction) onThread:self.ttThread withObject:nil waitUntilDone:NO];
}



@end

1.获取RunLoop只能使用 [NSRunLoop currentRunLoop] 或 [NSRunLoop mainRunLoop];
2.即使RunLoop开始运行,如果RunLoop 中的 modes 为空,或者要执行的mode里没有item,那么RunLoop会直接在当前loop中返回,并进入睡眠状态。
3.自己创建的Thread中的任务是在kCFRunLoopDefaultMode这个mode中执行的。
4.在子线程创建好后,最好所有的任务都放在AutoreleasePool中。

如果不执行下列语句:
[runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes];

不执行.png

执行下列语句:
[runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes];

执行后.png

可以看出我们添加了一个source0,这样runloop才运行起来。

其实这个例子只是简单制造一个常驻内存的线程,但是这个线程并不好控制结束,可以参考我的另外一篇文章iOS开发-RunLoop的退出方式

相关文章

  • iOS开发-使用Runloop实现线程保活、线程常驻

    保证线程的长时间存活在iOS开发过程中,有时一些花费时间比较长的操作阻塞主线程,导致界面卡顿,那么我们就会创建一个...

  • iOS底层原理——浅谈RunLoop

    RunLoop应用:线程保活 线程保活、控制销毁 iOS-浅谈RunLoop8iOS底层原理总结 - RunLoo...

  • iOS 多线程面试题(NSThread+runloop实现常驻线

    NSThread+runloop实现常驻线程 NSThread在实际开发中比较常用到的场景就是去实现常驻线程。 由...

  • RunLoop 02 - 应用(线程保活)

    RunLoop 02 - 应用(线程保活) PermanentThread PermanentThread 使用示例

  • # iOS线程保活(常驻线程)

    介绍 在日常的iOS开发中,遇到卡顿也是在所难免,一般卡顿是由于主线程处理耗时长的操作而造成线程一直在阻塞,那么我...

  • iOS底层探索 --- RunLoop(实战)

    日常开发中我们常用的RunLoop场景有: 线程保活 Timer相关 APP卡顿检测 线程保活首先我们应该达成的共...

  • iOS Runloop的理解与使用

    Runloop的概念 Runloop的存在主要就是为了线程保活,线程保活是为了线程能够及时的处理事件,不会在其执行...

  • iOS笔记-runloop

    runloop可以做什么? 处理crash 保持线程存活(线程保活) 监测、优化卡顿 线程和runloop有什么关...

  • runloop

    runloop跟线程师一一对应的。 自己创建的线程师没有runloop 如何实现一个常驻线程: 1 为当前线程开启...

  • iOS RunLoop(一)

    级别: ★★☆☆☆标签:「iOS」「RunLoop」「线程常驻」作者: 陈彬审校: QiShare团队 前言:这篇...

网友评论

    本文标题:iOS开发-使用Runloop实现线程保活、线程常驻

    本文链接:https://www.haomeiwen.com/subject/sscjmxtx.html