RunLoop

2016-09-18  本文已影响0人  薛定谔的熊

参考:http://www.cocoachina.com/ios/20150601/11970.html

Paste_Image.png Paste_Image.png

1、Timer

- (void)timer2
{
    // 调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    // 修改模式
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)timer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    // 定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
    // 定时器只运行在UITrackingRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
    // 定时器会跑在标记为common modes的模式下
    // 标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)run
{
    NSLog(@"----run");
}

2、Observer

- (void)observer
{
    // 创建observer
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        NSLog(@"----监听到RunLoop状态发生改变---%zd", activity);
    });
//    /* Run Loop 状态监听 */
//    typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
//        kCFRunLoopEntry = (1UL << 0),    //即将进入Loop
//        kCFRunLoopBeforeTimers = (1UL << 1),//即将处理Timer
//        kCFRunLoopBeforeSources = (1UL << 2),//即将处理Source
//        kCFRunLoopBeforeWaiting = (1UL << 5),//即将进入休眠
//        kCFRunLoopAfterWaiting = (1UL << 6),//刚从休眠中唤醒
//        kCFRunLoopExit = (1UL << 7),//即将退出Loop
//        kCFRunLoopAllActivities = 0x0FFFFFFFU
//    };
    // 添加观察者:监听RunLoop的状态
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
    
    // 释放Observer
/*
    CF的内存管理(Core Foundation)
    1.凡是带有Create、Copy、Retain等字眼的函数,创建出来的对象,都需要在最后做一次release
    * 比如CFRunLoopObserverCreate
    2.release函数:CFRelease(对象);
 */
    CFRelease(observer);
}

3、应用场景:


#import "ViewController.h"
#import "XMGThread.h"

@interface ViewController ()

/** 线程对象 */
@property (nonatomic, strong) XMGThread *thread;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.thread = [[XMGThread alloc] initWithTarget:self selector:@selector(execute) object:nil];
    [self.thread start];
}

- (void)execute
{
    NSLog(@"----------execute----%@", [NSThread currentThread]);
    //在当前模式添加端口(因为如果当前模式没有东西,RunLoop开启会马上退出)
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    // 启动(run执行首先会判断当前模式有没有东西,如果没有就会退出)
    [[NSRunLoop currentRunLoop] run];
    //移除
//    - (void)removePort:(NSPort *)aPort forMode:(NSRunLoopMode)mode;
    
    NSLog(@"---------");
    
    // 类似于上面的[[NSRunLoop currentRunLoop] run]
    //    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    //    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
}

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//这句方法实质是给self.thread这条线程中的RunLoop添加了Source(有source之后,RunLoop就不会退出了)
    [self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}
- (void)useImageView
{
    // 只在NSDefaultRunLoopMode模式下显示图片
    [self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"placeholder"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
}

需将timer手动添加到当前线程的RunLoop并开启,不然不会执行test方法。主线程下默认做了这些操作。


#import "ViewController.h"
#import "XMGThread.h"

@interface ViewController ()

/** 线程对象 */
@property (nonatomic, strong) XMGThread *thread;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.thread = [[XMGThread alloc] initWithTarget:self selector:@selector(execute) object:nil];
    [self.thread start];
}

//-(void)execute
//{
//   NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
//添加time到模式
//    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
//    [[NSRunLoop currentRunLoop] run];
//}

- (void)execute
{
//scheduledTimerWithTimeInterval创建的time默认会添加到RunLoop默认模式
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
    
    [[NSRunLoop currentRunLoop] run];
}

4、RunLoop自动释放池什么时候释放?

在RunLoop睡眠之前释放(KCFRunLoopBeforeWaiting)

上一篇 下一篇

猜你喜欢

热点阅读