NSThread 是輕量級(jí)的多線程開發(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)行中的軟件胁出,是動(dòng)態(tài)的
3. 一個(gè)操作系統(tǒng)可以對(duì)應(yīng)多個(gè)進(jìn)程型型,一個(gè)進(jìn)程可以有多條線程,但至少有一個(gè)線程
4. 同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程里的資源
2. 主線程
1. 進(jìn)程一啟動(dòng)就自動(dòng)創(chuàng)建
2. 顯示和刷新UI界面
3. 處理UI事件
3. 子線程
1. 處理耗時(shí)的操作
2. 子線程不能用來(lái)刷新UI
NSThread開辟線程的兩種方式
/*
*1.創(chuàng)建手動(dò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)建并自動(dò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)建并手動(dòng)開啟線程的方式)
thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage) object:nil];
//給線程起名字
thread.name = @"子線程";
// 開啟線程
[thread start];
}
/*
* 3抑淫、 在`子線程`中將url圖片轉(zhuǎn)成image對(duì)象
* downloadImage該方法的參數(shù)取決于創(chuàng)建線程時(shí)傳給object的參數(shù)
*/
- (void)downloadImage{
//將圖片的url地址轉(zhuǎn)化為data對(duì)象
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kUrl]];
//將data對(duì)象轉(zhuǎn)化為image對(duì)象
UIImage *image = [UIImage imageWithData:data];
//采用睡眠方式模擬1秒網(wǎng)絡(luò)延遲
// [NSThread sleepForTimeInterval:20];
/*
* 4. 回到主線程
* 方法updataUI將在主線程中執(zhí)行
* withObject:updateUI的參數(shù)
* waitUntilDone: 設(shè)為YES绷落,會(huì)阻塞當(dāng)前子線程,去主線程執(zhí)行updateUI方法始苇,也就是更新UI砌烁,直到UI更新完畢。設(shè)為NO,意味著在主線程updateUI方法執(zhí)行到一半時(shí)可能會(huì)被打斷去做其他線程的工作催式,也就是說(shuō)我主線程的UI還沒有顯示完就程序就跳出了主線程函喉。
*/
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
/*
* 查看打印結(jié)果
* number = 1 :線程的編號(hào),由系統(tǒng)設(shè)置荣月,主線程的編號(hào)為1
* name = main:指當(dāng)前所在的線程的名字叫做main,可以自己設(shè)置管呵,主線程的名字默認(rèn)是main,其他線程如果不給他設(shè)置名字默認(rèn)是nil
*/
NSLog(@"downlaodImage方法所在的線程 = %@",[NSThread currentThread]);
}
/*
* 5喉童、 在主線程中將image對(duì)象給UIImageView試圖
*/
- (void)updateUI:(UIImage *)image{
imageView.image = image;
NSLog(@"downlaodImage方法所在的線程 = %@",[NSThread currentThread]);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[thread start];
}
@end