本文介紹:這篇博客主要是描述的是RunLoop的啟動機制。內容屬於簡單的系類的。
一、RunLoop和線程的關系
每一個RunLoop對應一個線程。每一個線程都可以擁有一個RunLoop,這也就是說線程可以創建一個屬於自己的Runloop,也可以不創建自己的RunLoop。這都是根據程序內部的需求來決定的。這里需要注意的是:你創建一個runLoop但是你還必須要手動的讓其run。
二、main線程的RunLoop
主線程是灌注這個程序的。而與main線程相對應的RunLoop是在程序啟動的時候就開始生成。並且開始run。這些功能都是通過在這個函數實現的
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
三、自己創建的線程的runloop
你通過GDC創建了自己的一個線程。你想在自己的線程中使用runloop。那么你必須分兩步走:
(1)創建自己的runloop。(在這里說明一下,runloop是不能自己創建的。但是你可通過 getrunloop來獲取,源碼中是這樣寫的)
(2)讓runloop跑起來 CFRunLoopRun();
四、代碼分析
(1)在主線程中插入一個NSTimer源,你可以直接這些寫:
- (void)viewDidLoad { [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO]; }
-(void)run
{
NSLog(@"run");
}
因為是在主線程中運行這個代碼。所以NSTimer就自動的插入了主線程對應的RunLoop,而且你都不需要執行RunLoop Run的方法。
(2)在自己創建的線程中執行這段代碼
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. dispatch_queue_t queue = dispatch_queue_create("zhaoyan", 0); dispatch_async(queue, ^{ CFRunLoopRef runLoop = CFRunLoopGetCurrent(); [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO]; }); } -(void)run { NSLog(@"run"); }
這時候你會發現,在你的控制台中並不能輸出字符串 run,這是因為你在名為“zhaoyan”線程中執行,但是這個線程中並沒有創建runloop而且,runloop並沒有run起來,所以不能執行,所以我們應該更改一下代碼如下:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 如果你在 dispatch_queue_t queue = dispatch_queue_create("zhaoyan", 0); dispatch_async(queue, ^{ CFRunLoopRef runLoop = CFRunLoopGetCurrent(); // [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO]; NSTimer * timer =[[NSTimer alloc] initWithFireDate:[NSDate date] interval:0 target:self selector:@selector(run) userInfo:nil repeats:YES]; CFRunLoopAddTimer(runLoop, (CFRunLoopTimerRef)timer, kCFRunLoopDefaultMode); CFRunLoopRun(); }); } -(void)run { NSLog(@"run"); }
這樣我們開啟了這個線程的runloop 和 把這個run起來。但是上面的代碼中需要注意的是:[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO];注銷了,因為這段代碼是針對mian線程的。如果你這樣寫的話仍然不能打印字符串
如果有什么不足希望大家留言!
