參考:http://www.cocoachina.com/ios/20150601/11970.html
Paste_Image.png
Paste_Image.png
1醋奠、Timer
- (void)timer2
{
// 調(diào)用了scheduledTimer返回的定時器,已經(jīng)自動被添加到當前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
{
// 創(chuàng)建observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"----監(jiān)聽到RunLoop狀態(tài)發(fā)生改變---%zd", activity);
});
// /* Run Loop 狀態(tài)監(jiān)聽 */
// 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
// };
// 添加觀察者:監(jiān)聽RunLoop的狀態(tài)
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
// 釋放Observer
/*
CF的內(nèi)存管理(Core Foundation)
1.凡是帶有Create暇矫、Copy主之、Retain等字眼的函數(shù),創(chuàng)建出來的對象李根,都需要在最后做一次release
* 比如CFRunLoopObserverCreate
2.release函數(shù):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]);
//在當前模式添加端口(因為如果當前模式?jīng)]有東西,RunLoop開啟會馬上退出)
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
// 啟動(run執(zhí)行首先會判斷當前模式有沒有東西房轿,如果沒有就會退出)
[[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
{
//這句方法實質(zhì)是給self.thread這條線程中的RunLoop添加了Source(有source之后粤攒,RunLoop就不會退出了)
[self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}
-
在特定模式下執(zhí)行操作
- (void)useImageView
{
// 只在NSDefaultRunLoopMode模式下顯示圖片
[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"placeholder"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
}
-
子線程添加timer
需將timer手動添加到當前線程的RunLoop并開啟,不然不會執(zhí)行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創(chuàng)建的time默認會添加到RunLoop默認模式
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
4、RunLoop自動釋放池什么時候釋放纷妆?
在RunLoop睡眠之前釋放(KCFRunLoopBeforeWaiting)