天天看點

iOS 多線程技術1

iOS 多線程技術1

iOS 有三種多線程程式設計技術:

  • NSThread
  • NSOperation
  • GCD

它們的抽象程度由低到高,越高的使用起來越簡單.

NSThread

顯示調用 NSthread 類

  • 類方法
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
           
  • 執行個體方法
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
 [thread start]           

隐式調用

  • 開啟背景線程
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg           
  • 在主線程中運作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait           
  • 在指定的線程中執行,但是該線程必須具備 run loop
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait           

常見NSThread 的方法

+ (NSThread *)currentThread; //獲得目前線程
+ (void)sleepForTimeInterval:(NSTimeInterval)ti; //線程休眠
+ (NSThread *)mainThread; //主線程,即 UI線程
+ (BOOL)isMainThread; //判斷是否主線程
- (BOOL)isMainThread; //同上
- (BOOL)isExecuting; // 線程是否正在運作
- (BOOL)isFinished; // 線程是否已結束
           

Demo:

建立一個 lable, 實作程式運作起來一段時間後就能顯示一些内容,并且有一個 button 的按鈕,當點選時,模拟從網絡上重新整理出一張圖檔,從中我們要了解到當需要更新 UI 時,必須在主線程中進行.從使用者的角度來說,我看一張圖檔,不能影響的我在界面的其他操作,否則,這個 app 用着體驗太差,我可能會删掉不再使用.

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *lable;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    // 1.類方法
    [NSThread detachNewThreadSelector:@selector(dosomething:) toTarget:self withObject:@"detachNewThreadSelector"];

}
- (void)dosomething:(NSString * )string
{
    // 休眠5秒鐘,隻是模拟一個耗時的操作,如果操作耗時,就另起一個線程執行
    [NSThread sleepForTimeInterval:5];

    //更新 UI, 必須在主線程中進行  //NO 異步  YES 同步
    [self performSelectorOnMainThread:@selector(updateLable:) withObject:string waitUntilDone:NO];
    NSLog(@"%s",__func__);
}

- (void)updateLable:(NSString*)string
{
    _lable.text = string;
}

#pragma mark - image view
- (IBAction)btnAction:(UIButton *)sender {
    //執行個體方法
    NSString *urlStr =  @"http://img.hb.aicdn.com/5a8f57157b47284724d09ffd2da28369731f8144ac9c-1XdZKJ_fw658";
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(fetchImage:) object:urlStr];
    thread.name = @"lisi";
    [thread start];
}
- (void)fetchImage:(NSString*)urlStr
{
    // 進行耗時的網絡請求
    [NSThread sleepForTimeInterval:4];
    NSURL *url = [NSURL URLWithString:urlStr];
    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImage *image = [UIImage imageWithData:data];

    if ([[NSThread currentThread].name isEqualToString:@"lisi"]) {
        BOOL isMainThread = [[NSThread currentThread] isMainThread];
        NSLog(@">>>>>isMainThread:%d",isMainThread);
    }else{
        BOOL isMainThread = [[NSThread currentThread] isMainThread];
        NSLog(@"<<<<<<isMainThread:%d",isMainThread);
    }

    [self performSelectorOnMainThread:@selector(updateImageView:) withObject:image waitUntilDone:YES];

}
- (void)updateImageView:(UIImage *)image
{
    if ([[NSThread currentThread] isMainThread]) {
        NSLog(@"主線程:%s",__func__);
    }
    _imageView.image = image;
}           

運作結果:

2015-08-02 14:49:31.823 03-NSThreadDemo[3151:781147] -[ViewController dosomething:]

2015-08-02 14:49:34.539 03-NSThreadDemo[3151:781778] >>>>>isMainThread:0

2015-08-02 14:49:34.539 03-NSThreadDemo[3151:780917] 主線程:-[ViewController updateImageView:]

iOS 多線程技術1