RunLoop的應用

三、RunLoop的應用

 1.給子線程添加RunLoop

  在正常情況下、子線程在執行完selector方法後就會被釋放,如果需要從主線程中回到子線程就需要給子線程添加RunLoop

#import <Foundation/Foundation.h>

@interface ZLYThread : NSThread

@end

#import "ZLYThread.h"

@implementation ZLYThread
-(void)dealloc
{
    NSLog(@"子線程被釋放了");
}
@end

#import "ViewController.h"
#import "ZLYThread.h"
@interface ViewController ()
@property(nonatomic,strong) UIImageView * imageView;
@end
<pre name="code" class="objc">#import <UIKit/UIKit.h>


@interface ViewController : UIViewController


@end

@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; ZLYThread * thread = [[ZLYThread alloc] initWithTarget:self selector:@selector(showThread) object:nil]; [thread start]; }-(void)showThread{ NSLog(@"子線程執行完了");}

2016-09-03 15:56:25.070 Demo[4358:527692] 子線程執行完了
2016-09-03 15:56:25.071 Demo[4358:527692] 子線程被釋放了
根據打印結果可以看出,在子線程執行完成後,子線程就被釋放了


2.在子線程中添加RunLoop後就可以從主線程回到子線程,ViewController裏面的代碼如下

#import "ViewController.h"
#import "ZLYThread.h"
@interface ViewController ()
/****定時器(這裏不用帶*,因爲dispatch_source_t就是個類,內部已經包含了*)*****/
@property(nonatomic,strong) dispatch_source_t timer;
@property(nonatomic,strong) UIImageView * imageView;
@property(nonatomic,strong) ZLYThread * thread;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    ZLYThread  * thread = [[ZLYThread alloc] initWithTarget:self selector:@selector(showThread) object:nil];
    self.thread = thread;
    [thread start];
    
    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(50, 100, 200, 50);
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"主線程切換到子線程" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [self.view addSubview:button];
    
 }
-(void)buttonClick:(UIButton *)button
{
    [self performSelector:@selector(backSubThread) onThread:self.thread withObject:nil waitUntilDone:YES];
    NSLog(@"按鈕點擊事件執行完畢後才切換到子線程");
}
-(void)backSubThread
{
    
    NSLog(@"當前線程%@",[NSThread currentThread]);
}
-(void)showThread
{
    NSLog(@"子線程執行完了");
    /*
       【注】1.子線程的runloop需要自己動手創建,手動開啓
            2.子線程的runloop裏面至少要有一個source或是timer
     */
   
    [[NSRunLoop currentRunLoop] addPort:[NSMachPort  port] forMode:NSDefaultRunLoopMode];
     [[NSRunLoop currentRunLoop] run];
}
打印結果如下
2016-09-03 16:30:23.844 Demo[4714:590326] 子線程執行完了
2016-09-03 16:30:28.024 Demo[4714:590326] 當前線程<ZLYThread: 0x7fae825bb8d0>{number = 2, name = (null)}
2016-09-03 16:30:28.025 Demo[4714:590188] 按鈕點擊事件執行完畢後才切換到子線程
【注意】在[self performSelector:@selector(backSubThread) onThread:self.threadwithObject:nil waitUntilDone:YES];方法中第四個參數爲NO時 是等按鈕點擊事件執行完畢時,再執行子線程。

3.自動釋放池創建和釋放的時間

  第一次創建時間爲進入RunLoop的時候,

 最後一次釋放時間爲RunLoop退出的時候

 當RunLoop將要睡覺的時候會釋放,然後創建一個新的自動釋放池準備下一次循環




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章