天天看點

iOS開發多線NSThread(三)

NSThread是在GCD,NSThread,NSOperationQueue三種方法裡面相對輕量級的,但需要管理線程的生命周期、同步、加鎖問題,這會導緻一定的性能開銷

一、NSThread簡單介紹蘋果開發文檔連結

1、對象方法初始化線程

- (instancetype)init NS_AVAILABLE(10_5, 2_0) NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);
- (instancetype)initWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));           

2、類方法初始化線程

+ (void)detachNewThreadWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;           

3、常用參數

// 設定線程的優先級(0.0 - 1.0,1.0最進階)
@property double threadPriority NS_AVAILABLE(10_6, 4_0);
//給線程起名字
@property (nullable, copy) NSString *name NS_AVAILABLE(10_5, 2_0);
//判斷是否為主線程(類方法)
@property (class, readonly) BOOL isMainThread NS_AVAILABLE(10_5, 2_0); 
//擷取主線程(類方法)
@property (class, readonly, strong) NSThread *mainThread NS_AVAILABLE(10_5, 2_0);           

4、線程通信

//在主線程上執行操作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
//在指定線程上執行操作
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
//立即建立一個線程并執行selector方法多用于在伺服器端擷取完資料通過背景使用多線程方式自動更新UI
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);           

二、NSThread簡單使用

1、下載下傳圖檔測試

- (IBAction)downloadImageClick:(id)sender {
    BOOL result = [NSThread isMainThread];
    NSLog(@"downloadImageClick%d",result);
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(download:) object:nil];
    thread.name = @"downloadthread";
    [thread start];
    [NSThread detachNewThreadWithBlock:^{
        NSThread *th = [NSThread currentThread];
        NSLog(@"threadName - %@",th);
    }];
}

- (void)download:(NSThread *)thread{
    BOOL result = [NSThread isMainThread];
    NSLog(@"download%d",result);
    NSLog(@"threadName - %@",[NSThread currentThread].name);
#define IMAG_URL @"http://avatar.csdn.net/C/2/6/1_u010067452.jpg"
    NSString *url = [IMAG_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [UIImage imageWithData:data];
    //線程通信
    NSLog(@"before");
    [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
    //waitUntilDone 是否不等待主線程指向完該方法再往下執行
    //no 子線程不等待主線程 直接向下繼續運作
    //yes 子線程需要等待 主線程執行完setImage方法再執行
    NSLog(@"after");
}

- (void)setImage:(UIImage *)image{
    //主線程執行 image子線傳遞 完成線程之間的通信
    NSLog(@"setImage");
    self.imageView.image = image;
    
}
           

2、exit使用

- (void)test{
    //(1)通過類方法開辟子線程
    NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(printA) object:nil];
    [thread1 start];//開始執行printA 執行過程中 線程間是互相獨立 不會主線程的正常執行
//    [thread1 cancel];//取消
    //【注意】cancel取消線程 并不是将線程銷毀 而是給線程打上一個标記 根據線程的取消标記 判斷是否需要對線程做一些處理 打上标記後 線程依然正常執行 指導執行結束退出
    [NSThread exit];//子線程退出 結束 不是對象方法 而是類方法 主動退出
    [NSThread detachNewThreadSelector:@selector(printB) toTarget:self withObject:nil];
    //一旦建立 自動啟動 不需要發送任何啟動子線程的指令
}
- (void)printB{
  
    for (int i = 0; i < 5; i++) {
        NSLog(@"printB");
    }
}

- (void)printA{
    for(int i = 0; i < 5; i ++){
        NSLog(@"printA");
    }
}
           

列印結果為

2017-03-20 16:42:24.934 NSThreadProject[6911:303193] printA
2017-03-20 16:42:24.935 NSThreadProject[6911:303193] printA
2017-03-20 16:42:24.935 NSThreadProject[6911:303193] printA
2017-03-20 16:42:24.935 NSThreadProject[6911:303193] printA
2017-03-20 16:42:24.936 NSThreadProject[6911:303193] printA           

繼續閱讀