iOS runloop 创建一个和App生命周期相同的线程


//
//  NetWorkRequestThread.m
//  test_nstherad_port_02
//  Created by jeffasd on 16/7/25.
//  Copyright © 2016年 jeffasd. All rights reserved.
//  创建一个和app生命周期相同的线程并一直请求发起网络请求

#import "NetWorkRequest.h"

@interface NetWorkRequest ()

@property (nonatomic, strong) NSTimer *timer;

@end

@implementation NetWorkRequest

+ (instancetype)shareNetRequest{
    
    static NetWorkRequest *_networkRequest = nil;
    if (_networkRequest == nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _networkRequest = [[self alloc] init];
        });
    }
    return _networkRequest;
}

+ (NSThread *)shareNetworkRequestThread{
    
    static NSThread *_networkRequestThread = nil;
    if (_networkRequestThread == nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkrRequestThreadEntryPoint:) object:nil];
            [_networkRequestThread start];
        });
    }
    return _networkRequestThread;
}

+(void)networkrRequestThreadEntryPoint:(id)__unused object{
    
    [[NSThread currentThread] setName:@"networkRequestThread"];
    NSRunLoop *runloop = [NSRunLoop currentRunLoop];
    //添加一个port监听让runloop一直处于运行状态 好让thread不被回收
    [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
    
#if 0
    BOOL isRuning = YES;
    while (isRuning) {
        //此方法添加的runloop可以用CFRunLoopStop(runLoopRef)来停止RunLoop的运行
        //子线程中的runmode不能使用NSRunLoopCommonModes
        //    [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        //一直监听线程是否有消息输入(default模式),有当前线程就开始工作,没有就休眠。进行一次消息轮询,如果没有任务需要处理的消息源,则直接返回
        BOOL isRuning = [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        //此方法停止runloop要设置isRuning为NO 不是很方便 使用 CFRunLoopRun(); 方法来代替
        NSLog(@"isRuning is %@", isRuning ? @"YES" : @"NO");
    }
#endif
    
    //可以很方便暂停runloop循环
    CFRunLoopRun();
    
}

- (void)start{
    
    [self performSelector:@selector(startNetWorkRequest) onThread:[[self class] shareNetworkRequestThread] withObject:nil waitUntilDone:NO];
}

- (void)startNetWorkRequest{
    
//    NSThread *currentThread = [NSThread currentThread];
//    NSLog(@"currentThread is %@", currentThread);
//    NSLog(@"runLoop is %@", [NSRunLoop currentRunLoop]);
    NSLog(@"do Something");
    
    self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(getMessageFormRemoteService) userInfo:nil repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    
}

- (void)getMessageFormRemoteService{
    
    NSLog(@"currentThread is %@", [NSThread currentThread]);
    NSLog(@"service -- ");
}

- (void)cancel{
    
    NSThread *therad = [[self class] shareNetworkRequestThread];
    
    NSLog(@"the thread is %@", therad.executing ? @"YES" : @"NO");
    NSLog(@"the thread is %@", therad.finished ? @"YES" : @"NO");
    NSLog(@"the thread is %@", therad.cancelled ? @"YES" : @"NO");
    
    NSLog(@"the thread is %@", therad);
    
    [self performSelector:@selector(cancelNetWorkRequest) onThread:[[self class] shareNetworkRequestThread] withObject:nil waitUntilDone:NO];
}

- (void)cancelNetWorkRequest{
    
    NSThread *currentThread = [NSThread currentThread];
    NSLog(@"currentThread is %@", currentThread);
    
    CFRunLoopStop([NSRunLoop currentRunLoop].getCFRunLoop);
//    CFRunLoopStop(CFRunLoopGetCurrent());
}

@end


你可能感兴趣的:(iOS_网络)