NSThread

NSThread 是輕量級的多線程開發(fā),使用并不復(fù)雜,但使用NSThread需要自己管理線程的聲明周期。

1.線程與進(jìn)程的關(guān)系

1. 線程是CPU執(zhí)行任務(wù)的基本單位,一個(gè)進(jìn)程能有多個(gè)線程,但同時(shí)只能執(zhí)行一個(gè)任務(wù)
2. 進(jìn)程就是運(yùn)行中的軟件,是動態(tài)的
3. 一個(gè)操作系統(tǒng)可以對應(yīng)多個(gè)進(jìn)程,一個(gè)進(jìn)程可以有多條線程,但至少有一個(gè)線程
4. 同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程里的資源

2. 主線程

1. 進(jìn)程一啟動就自動創(chuàng)建
2. 顯示和刷新UI界面
3. 處理UI事件

3. 子線程

1. 處理耗時(shí)的操作
2. 子線程不能用來刷新UI

NSThread開辟線程的兩種方式

    /*
     *1.創(chuàng)建手動開啟方式

     * target: 信息發(fā)送者
    
     * selector: 方法選擇器選擇一個(gè)方法
     
     * object: 如果上面選擇的方法有參數(shù),則object便是這個(gè)方法的參數(shù)
     */
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:@"thread"];
    // 開啟線程
    [thread start];


    /*
     *2.創(chuàng)建并自動開啟方法
     */
    [NSThread detachNewThreadSelector:@selector(thread1:) toTarget:self withObject:@"thread1"];

下面是 多線程加載一張圖片 實(shí)例



#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()
{
    UIViewController *VC;
}
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    
    VC = [[UIViewController alloc]init];
    
    VC.view.backgroundColor = [UIColor whiteColor];
    
    VC.title = @"NSThread";
    
    self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:VC];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    
    button.frame = CGRectMake(100, 200, 0,0);
    
    [button setTitle:@"多線程加載一張圖片" forState:UIControlStateNormal];
    
    [button sizeToFit];
    
    [VC.view addSubview:button1];
    
    [button addTarget:self action:@selector(clickBtn1) forControlEvents:UIControlEventTouchUpInside];
     [button1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    

 return YES;
}

- (void)clickBtn1{
    
    [VC.navigationController pushViewController:[ViewController new] animated:YES];
}
}

Viewcontroller.m

#import "ViewController.h"

#define kUrl @"http://store.storeimages.cdn-apple.com/8748/as-images.apple.com/is/image/AppleInc/aos/published/images/s/38/s38ga/rdgd/s38ga-rdgd-sel-201601?wid=848&hei=848&fmt=jpeg&qlt=80&op_sharpen=0&resMode=bicub&op_usm=0.5,0.5,0,0&iccEmbed=0&layer=comp&.v=1454777389943"

@interface ViewController ()
{
    UIImageView *imageView;
    NSThread *thread;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"多線程加載一張圖片";
    self.edgesForExtendedLayout = UIRectEdgeNone;

    
    // 1、在self.view上放一個(gè)UIImageView試圖
     
    imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 200, 200)];
    [self.view addSubview:imageView];
    
    
    
     //2、 開辟一條子線程(我這里采用創(chuàng)建并手動開啟線程的方式)
      thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage) object:nil];
    
    //給線程起名字
    thread.name = @"子線程";
    
    // 開啟線程
    [thread start];
    
    
    
}

/*
 * 3、 在`子線程`中將url圖片轉(zhuǎn)成image對象
 
 *  downloadImage該方法的參數(shù)取決于創(chuàng)建線程時(shí)傳給object的參數(shù)
 
 */
- (void)downloadImage{
    
    
    //將圖片的url地址轉(zhuǎn)化為data對象
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kUrl]];
    
    //將data對象轉(zhuǎn)化為image對象
    UIImage *image = [UIImage imageWithData:data];
    
    //采用睡眠方式模擬1秒網(wǎng)絡(luò)延遲
//    [NSThread sleepForTimeInterval:20];
    
    /* 
     * 4. 回到主線程
     
     * 方法updataUI將在主線程中執(zhí)行
     
     * withObject:updateUI的參數(shù)
     
     * waitUntilDone: 設(shè)為YES,會阻塞當(dāng)前子線程,去主線程執(zhí)行updateUI方法,也就是更新UI,直到UI更新完畢。設(shè)為NO,意味著在主線程updateUI方法執(zhí)行到一半時(shí)可能會被打斷去做其他線程的工作,也就是說我主線程的UI還沒有顯示完就程序就跳出了主線程。
     */
    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
    
    
    /*
     
     * 查看打印結(jié)果
     
     * number = 1 :線程的編號,由系統(tǒng)設(shè)置,主線程的編號為1
     
     * name = main:指當(dāng)前所在的線程的名字叫做main,可以自己設(shè)置,主線程的名字默認(rèn)是main,其他線程如果不給他設(shè)置名字默認(rèn)是nil
     
     */
    NSLog(@"downlaodImage方法所在的線程 = %@",[NSThread currentThread]);
}

/*
 * 5、 在主線程中將image對象給UIImageView試圖
 */

- (void)updateUI:(UIImage *)image{
    
    imageView.image = image;
    
    NSLog(@"downlaodImage方法所在的線程 = %@",[NSThread currentThread]);
    
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [thread start];
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容