文章标题

来源:互联网 发布:js yui在线压缩 编辑:程序博客网 时间:2024/06/16 06:04

/*
当用户下载资源、进行图像处理、耗时数据处理等任务的时候 往往希望操作这个任务的时候,其他的操作不会被中断 这时候 就用到了多线程

在单线程中 一个线程只能执行一个任务。一个任务处理不完另一个任务就不能开始,这样会影响任务的体验 让用户感觉APP卡顿

现在苹果手机都是多核处理器,这样我们可以把一个任务分成多个步骤,在不要求按照步骤的情况下 使用多线程 既能解决线程阻塞 增加用户体验 又能充分利用多核处理器运行能力

每个应用程序的内部,存在一个或者多个执行的线程,它同时或在一个几乎同时执行不同的操作

面试题:
什么是进程 什么是线程 什么是多线程

进程与线程: 每个系统运行的程序都是一个进程,每个进程里面包括了一到多个线程线程是一组指令的集合,程序中一个单一的顺序控制流程,是一个程序中独立运行的程序片段(一个应用程序里面  单一的顺序控制执行的一个任务)

程序运行后,系统会创建一个叫做(main)主线程的线程,所有的UI控件都必须运行在主线程中,所以有人也叫它UI线程 如果将所有的任务都放在主线程中,容易造成UI阻塞

多线程: 在同一个应用程序内,同时运行多个线程,完成不同的工作,叫做多线程

为什么使用多线程: 单线程的应用程序中,代码沿直线执行,只有前面的代码执行完了,才会去执行后面的代码,中间这段时间,实际上就处于等待状态。当用户执行某项操作,比如上传文件 或者下载文件,主线程会执行这个任务,直到上传结束后,主线程才能继续后面的工作,在这段时间内,主线程处于忙碌状态,不会对用户请求作出任何反应,,最为直观地界面就是任务卡死,特别是操作这个任务需要大量的时间的时候更为明显

ios中有三种多线程策略供开发者使用:NSThread、NSOperation(基类不可以直接使用 只能使用它的子类)
、GCD(Grand Central Dispatch)
// GCD 苹果 推荐的一种 实现多线程的方式

NSThread:轻量级(对系统框架的依赖程度)
NSThread:是这三种策略里面相对轻量级的,需要自己去管理他的生命周期,以及线程之间的同步,线程共享同一应用程序的部分内存空间,他们拥有相对数据相同的访问权限,所以得协调多个线程对同一数据的访问,常用的做法是在访问之前加锁,这会导致一定的性能开销

*/

import “ViewController.h”

@interface ViewController ()
{

UIImageView *pointView;

}
@end

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    pointView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    pointView.backgroundColor = [UIColor redColor];
    pointView.layer.cornerRadius = 100/2;
    pointView.layer.masksToBounds = YES;
    [self.view addSubview:pointView];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
    [self.view addGestureRecognizer:tap];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(300, 20, 50, 50);
    [button setTitle:@”下载” forState:UIControlStateNormal];
    [button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];

}

-(void)tap:(UITapGestureRecognizer *)sender
{

// 打印当前线程
NSLog(@”当前线程:%@”, [NSThread currentThread]);
// name = main 表示主线程

pointView.center = [sender locationInView:self.view];

}

//注意: 开辟线程 去执行另外一个任务 (当线程的任务执行完毕) 主线程 需要的数据 必须得再次更新
//每一个线程都是 独立的代码片段 当主线程 触发下载任务 开辟另一个线程的时候 (主线程 会继续执行) 子线程 也会独立执行 (主线程 不知道子线程 什么时候执行完毕)

-(void)action:(UIButton *)sender
{
// 点击Button的时候开辟一个线程

// 使用 alloc]init]; 必须手动启动线程
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(operation) object:nil];

// 给线程取一个名字:
thread.name = @”下载图片”;

[thread start];  //手动启动线程

// 多个线程同时访问一个数据

NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(operation) object:nil];//    给线程取一个名字:thread2.name = @"下载图片2";[thread2 start];  //手动启动线程

// 开启线程的方法二:
// 直接开启 不需要手动开启 不能给它取名字 但是能给.name赋值
// [NSThread detachNewThreadSelector:@selector(operation) toTarget:self withObject:nil];

}

-(void)operation
{
NSLog(@”当前线程:%@”, [NSThread currentThread]);

sleep(5);  //模拟下载耗时任务的操作

// 当操作完毕之后 刷新UI 在主线程里面刷新
// 从子线程回到主线程取刷新UI界面
[self performSelectorOnMainThread:@selector(upDataUI:) withObject:[NSData dataWithContentsOfURL:[NSURL URLWithString:@”http://file.bmob.cn/M01/33/41/oYYBAFXcMhaARlGBAABOZfJ7P6Y062.png“]] waitUntilDone:YES];

// NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@”http://file.bmob.cn/M01/33/41/oYYBAFXcMhaARlGBAABOZfJ7P6Y062.png“]];

}

//主线程刷新UI
-(void)upDataUI:(NSData *)data
{

pointView.image = [UIImage imageWithData:data];

}

  • (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

@end

0 0