【iOS】RunLoop学习

1、Apple的源码

2、练习demo

//
//  ViewController.m
//  RunloopTest
//
//  Created by super on 2020/7/29.
//  Copyright © 2020 super. All rights reserved.
//

#import "ViewController.h"
#import "MyCell.h"

@interface ViewController ()<NSPortDelegate,UITableViewDataSource>
/** tableView 用于测试滑动后runloop mode的变化 */
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIButton *button;
@end

@implementation ViewController

/** 关于iOS runloop的优秀资料
 https://opensource.apple.com/source/CF/CF-1153.18/CFRunLoop.c.auto.html
 https://blog.ibireme.com/2015/05/18/runloop/
 https://github.com/ming1016/study/wiki/CFRunLoop
 https://v.youku.com/v_show/id_XODgxODkzODI0.html
 */

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self.tableView registerNib:[UINib nibWithNibName:@"MyCell" bundle:nil] forCellReuseIdentifier:@"MyCell"];

    //runloop1
//    [self runloop1];
    
    //runloop2
//    [self runloop2];
    
    //runloop3
//    [self runloop3];
    
    
}

/// 普通的NSTimer与runloop
- (void)runloop1
{
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(runloop1Action) userInfo:nil repeats:YES];
    /* 滑动tableView,系统切换到UITrackingRunLoopMode。 NSRunLoopCommonModes 包含此模式,所以timer正常执行,
     * NSDefaultRunLoopMode 滑动tableView timer停止执行 */
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

///子线程线程保活
- (void)runloop2
{
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object: nil];
    [thread start];
}

/// performSelector:onThread:withObject:waitUntilDone 与 runloop
- (void)runloop3
{
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(enterPoint) object:nil];;
    [thread start];
    
    NSArray *symbols = [NSThread callStackSymbols];
    NSLog(@"symbols--->%@",symbols);
    /** performSelector:等方法内部会创建了一个NSTimer,并添加到当前线程的runloop中 */
    [self performSelector:@selector(doSome) onThread:thread withObject:nil waitUntilDone:YES];
}

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{
    return 10;
}

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell" forIndexPath:indexPath];
    
    return cell;
}


#pragma mark - Action

- (void)runloop1Action
{
    NSLog(@"--->runloop1Action");
}

- (void)newThread
{
    NSLog(@"--->newThread");
    
    @autoreleasepool {
        //子线程创建timer
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(increseCounter:) userInfo:nil repeats:YES];
        
        //子线程开启runloop
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
}


- (void)increseCounter:(NSTimer *)timer
{
    NSLog(@"--->increseCounter");
}

- (void)enterPoint
{
    @autoreleasepool {
        [[NSThread currentThread] setName:@"super"];
        [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
        /* run方法一定要执行,否则报错
         Terminating app due to uncaught exception 'NSDestinationInvalidException', reason: '*** -[ViewController performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform */
        [[NSRunLoop currentRunLoop] run];
    }
}

- (void)doSome
{
    NSLog(@"--->doSome");
}

- (IBAction)buttonAction:(id)sender {
    //点击按钮打印线程堆栈
    NSArray *symbols = [NSThread callStackSymbols];
    NSLog(@"symbols--->%@",symbols);
}

@end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值