RunLoop启动方法

- (void)run; // 默认模式
- (void)runUntilDate:(NSDate *)limitDate;
- (BOOL)runMode:(NSRunLoopMode)mode beforeDate:(NSDate *)limitDate;

第一种会一直运行下去,并且一直在NSDefaultRunLoopMode模式下,重复调用runMode:beforeDate:方法。

第二种会在超时时间之前一直在NSDefaultRunLoopMode模式下调用runMode:beforeDate:方法。

第三种则会在超时时间到达或者第一个inputsource被处理前一直调用runMode:beforeDate:方法。


可以通过NSRunLoop的分类查看

- (void)viewDidLoad {
    [super viewDidLoad];
    _thread = [[NSThread alloc] initWithTarget:self selector:@selector(createRunLoopInNewThread) object:nil];
    [_thread setName:@"RunLoopDemo"];
    [_thread start];

}



- (void)createRunLoopInNewThread {
    _theRL = [NSRunLoop currentRunLoop];
    _port = (NSMachPort *)[NSMachPort port];
    // 添加一个端口作为输入源
    [_theRL addPort:_port forMode:NSDefaultRunLoopMode];
    
    
    [_theRL run];

}

NSRunLoop+Hook.h

#import <Foundation/Foundation.h>

@interface NSRunLoop (Hook)

@end

NSRunLoop+Hook.m

#import "NSRunLoop+Hook.h"
#import <objc/runtime.h>
@implementation NSRunLoop (Hook)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self _swizzleImpWithOrigin:@selector(runMode:beforeDate:) swizzle:@selector(xd_runMode:beforeDate:)];
    });
}

+ (void)_swizzleImpWithOrigin:(SEL)originSelector swizzle:(SEL)swizzleSelector {

    Class _class = [self class];
    Method originMethod = class_getInstanceMethod(_class, originSelector);
    Method swizzleMethod = class_getInstanceMethod(_class, swizzleSelector);

    IMP originIMP = method_getImplementation(originMethod);
    IMP swizzleIMP = method_getImplementation(swizzleMethod);

    BOOL add = class_addMethod(_class, originSelector, swizzleIMP, method_getTypeEncoding(swizzleMethod));

    if (add) {
        class_addMethod(_class, swizzleSelector, originIMP, method_getTypeEncoding(originMethod));
    } else {
        method_exchangeImplementations(originMethod, swizzleMethod);
    }
}

- (BOOL)xd_runMode:(NSRunLoopMode)mode beforeDate:(NSDate *)limitDate {

    NSThread *thread = [NSThread currentThread];

    // 这里我们只对自己创建的线程runloop的`runMode:beforeDate:`方法进行修改.
    if ([thread.name isEqualToString:@"RunLoopDemo"]) {
        NSLog(@"RunLoopDemo线程 ");
        return YES; //如果这里返回`NO`, runloop会立刻退出, 故要返回`YES`进行验证.
    }

    NSLog(@"runloop+hook: 其他可能未知的线程%@ ", thread.name);
    return [self xd_runMode:mode beforeDate:limitDate];
}

@end




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值