GCD定时器
@property (nonatomic, strong) dispatch_source_t timer;
int count = 0;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
dispatch_queue_t queue = dispatch_get_main_queue();
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, interval, 0);
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"------------%@", [NSThread currentThread]);
count++;
});
dispatch_resume(self.timer);
}
NSTimer
- (void)timer
{
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)timer2
{
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
}
- 02 第二部分 05Quartz2D 08 雪花定时器 动画计时器
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
ImageView显示
- (void)useImageView
{
[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"placeholder"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
}
PerformSelector
self performSelector:<#(nonnull SEL)#> withObject:<#(nullable id)#> afterDelay:<#(NSTimeInterval)#> inModes:<#(nonnull NSArray<NSRunLoopMode> *)#>
[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"placeholder"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
常驻线程
- 常驻线程:线程不死:经常要在后台(子线程)做耗时操作 如:==在后台监控用户的操作==
#import <Foundation/Foundation.h>
@interface XMGThread : NSThread
@end
#import "XMGThread.h"
@implementation XMGThread
- (void)dealloc
{
NSLog(@"%@ --- dealloc", self);
}
@end
@property (nonatomic, strong) XMGThread *thread;
self.thread = [[XMGThread alloc] initWithTarget:self selector:@selector(run) object:nil];
self.thread.name = @"开启的常驻线程";
[self.thread start];
- (void)run
{
NSLog(@"----------run----%@", [NSThread currentThread]);
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
NSTimer *timer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(show) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
NSLog(@"---------");
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}
- (void)test
{
NSLog(@"----------test----%@", [NSThread currentThread]);
}
自动释放池
- (void)execute
{
@autoreleasepool{
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
}
RunLoop面试题
- 什么是runLoop?
- 从字面意思就是运行循环
- 内部是一个do - while 循环,在循环内部不断处理各种事件(比如 source、timeer、observer)
- 一个线程对应一个RunLoop,主线程runLoop 默认启动,子线程runLoop要手动启动
- runLoop 只能选择一个模式启动,如果当前模式中没有source(source0、source1)、timer,那么就直接退出runLoop
- 你在开发中怎么使用runLoop
- 开启一个常驻线程,(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)
- 可以控制定时器在特定模式下运行
- 可以让某些事件(行为,任务)在某种特定的模式下运行
- 可以添加Observer监听runLoop的状态,比如监听点击状态的处理(在点击之前处理一些事情)
- 自动释放池在什么时候释放?
- 在runLoop 睡眠之前释放 ==kCFRunLoopAfterWaiting==
- 通过Observe监听RunLoop的状态,一旦监听到在RunLoop即将进入睡眠等待状态就释放自动释放池(kCFRunLoopBeforeWaiting)
自动释放池和RunLoop
- kCFRunLoopEntry; //创建一个自动释放池
- kCFRunLoopBeforeWaiting; //销毁自动释放池,创建一个新的自动释放池
- kCFRunLoopExit; //销毁自动释放池