IOS runs performSelector and NSTimer in child threads

First of all, this involves the concept of NSRunLoop, which I will briefly say. A main thread needs NSRunLoop when calling its own or other class functions, while the main thread has NSRunLoop by default. But the sub thread does not, so when the sub thread calls other functions, it will fail. If we turn on NSRunLoop, we can use it. This NSRunLoop is not created by us, but borrowed from the main thread.

Code it first, say it again

//
//  ViewController.m
//  BmobTest
//
//  Created by shanreal-iOS on 2017/12/9.
//  Copyright © 2017 shanreal.LongZhenHao. All rights reserved
//

#import "ViewController.h"
#import "TestBean.h"
#import "MyTableViewCell.h"
#import "DetailTableViewCell.h"

@interface ViewController ()

@property(nonatomic,strong)UIButton* btn;
@property(nonatomic,strong)UIButton* btn2;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _btn = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 100, 30)];
    [_btn setTitle:@"button" forState:UIControlStateNormal];
    [_btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    _btn.font = [UIFont systemFontOfSize:20];

    [_btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_btn];

    _btn2 = [[UIButton alloc]initWithFrame:CGRectMake(20, 60, 100, 30)];
    [_btn2 setTitle:@"two" forState:UIControlStateNormal];
    [_btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    _btn2.font = [UIFont systemFontOfSize:20];

    [_btn2 addTarget:self action:@selector(btn2Click) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_btn2];

}

-(void)btnClick{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{



        [self performSelector:@selector(backGroundThread) onThread:[NSThread currentThread] withObject:nil waitUntilDone:NO];
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop run];

    });

}

- (void)backGroundThread{

    NSLog(@"%u",[NSThread isMainThread]);

    NSLog(@"execute %s",__FUNCTION__);

}

-(void)btn2Click{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{



        NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];

        [myTimer fire];

        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop run];
    });

}
- (void)timerAction{

    NSLog(@"timer action");

}
@end

This NSRunLoop must be placed after the function to be executed. If not, the function may not be executed. I think it may be a jump function before I need NSRunLoop instead of preparing before I jump.

Tags: iOS

Posted on Sun, 03 May 2020 07:21:03 -0700 by harvey