您的位置:首页 > 运维架构

多线程知识点 自定义Operation

2015-10-04 10:24 369 查看
标题

自定义Operation
在ViewController.m里面 导入DownLoadOperation 这个类
#import "ViewController.h"
#import "DownLoadOperation.h"

// 代理传值:导入代理
@interface ViewController ()<DownLoadOperationDelegate>
{
定义一个全局变量
UIImageView *imageView;

}
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveNot:) name:@"下载完成" object:nil];

imageView = [[UIImageView alloc]initWithFrame:self.view.frame];

[self.view addSubview:imageView];

DownLoadOperation * downLoad = [[DownLoadOperation alloc]initWithDownLoadMessageURL:@"http://file.bmob.cn/M01/37/F1/oYYBAFXdo8yANhgHAABx04fZA8s908.png"];

// 5. 代理传值:挂上代理
downLoad.delegate = self;
// 如果调用Block的时候
还没有找到Block就会崩溃(与OC里面调用方法一样
如果调用的方法没有去写
也会崩溃)
// downLoad.bringImageBlock = ^(UIImage *image){
//
//
// imageView.image = image;
//
// };

// [downLoad start];

// 异步加载图片
NSOperationQueue *queue = [[NSOperationQueue alloc]init];

queue.maxConcurrentOperationCount = 1;

[queue addOperation:downLoad];

}

// 通知传值
//- (void)receiveNot:(NSNotification *)sender
//{
//
//NSLog(@"%@",sender.object);
// imageView.image = sender.object;
//
//}

// 6.代理传值:实现代理方法
- (void)didFinshDownLoadWithImage:(UIImage *)image
{

imageView.image = image;

}

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

@end

在DownLoadOperation.h 里面导入UIKit/UIKit.h框架
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

// 1.声明一个代理方法
@protocol DownLoadOperationDelegate <NSObject>

- (void)didFinshDownLoadWithImage:(UIImage *)image;

@end

@interface DownLoadOperation : NSOperation
{

// 声明一个全局变量
NSString *urlString;
}

//nonatomic 在多线程里面
使用nonatomic 不能保证
在多线程 里面数据传递的安全
//@property(atomic,retain)UIImage *imageContent;

// @property(atomic,copy)void(^bringImageBlock)(UIImage *image);

// 写一个下载图片的operation需要URL
- (instancetype)initWithDownLoadMessageURL:(NSString *)url;

// 2. 声明属性作为代理的接口
@property(assign)id<DownLoadOperationDelegate>delegate;

@end

在 DownLoadOperation.m里面

- (instancetype)initWithDownLoadMessageURL:(NSString *)url
{

self = [super init];
if (self) {

urlString = url;

}

return self;
}

//Operation 具体操作写在main里面 start的时候会执行里面的操作
- (void)main
{

NSLog(@"自定义完了Operation方法");
// 具体下载的操作
NSURL *url = [NSURL URLWithString:urlString];

// 不管同步还是异步此方法都要有
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

UIImage *image = [UIImage imageWithData:data];

NSLog(@"%@",image);

// 使用Block传值
// self.bringImageBlock(image);

// 使用通知传值

// [[NSNotificationCenter defaultCenter]postNotificationName:@"下载完成" object:image];

// 3.代理传值:调用代理方法

[self.delegate didFinshDownLoadWithImage:image];

}
线程部分

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

2.在单线程中一个线程只能执行一个任务,一个任务处理不完 另一个任务就不能开始 这样会影响用户体验 让用户感觉 APP卡顿
每个应用程序的内部,存在一个或多个执行线程,它同时 或 在一个几乎同时执行不同的操作

面试题: 什么是进程? 什么是线程?什么是多线程
进程与线程:每个系统运行的程序都是一个进程,每个进程里面包含了多个线程
进程: 是指在系统中正在运行的一个应用程序
线程 :是一组指令的集合,程序中一个单个的顺序控制流程,是一个程序中,独立运行的程序片段(一个应用程序里面 单一的顺序控制执行的一个任务)
程序运行后,系统会创建一个叫做(main)主线程的线程,所有的UI控件都必须运行在主线程中,所以也有人叫UI线程
如果将所有的任务都放在主线程中,容易造成阻塞
多线程:在同一应用程序内,同时运行多个线程,完成不同的工作,叫做多线程
为什么要使用多线程:单线程的运用程序中,代码沿直线执行,只有前面的代码执行完了,才会执行后面的代码,中间这段时间,实际上就处于等待状态。当用户执行某项操作,比如上传文件,或则下载文件,主线程会执行这个任务,直到上传结束,主线程才能继续后面的工作,在这段时间内,主线程处于忙碌状态,不会对用户的请求作出任何回应,

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

轻量级: 对系统框架的依赖性程度
NSThread:是这三种策略里面相对轻量级的,需要自己去管理它的生命周期,以及线程之间的同步,线程共享一应用程序的部分内存空间,他们拥有数据相同的访问权限,所以的协调多个线程对同一数据的访问,长做的做法是在访问值之前加锁,
第二部分
NSOperation线程:
NSOperation
是一个基类 (抽象类)不能直接使用必须使用他的子类
他默认时在当前线程
进行操作
常与NSOperationQueue
一起使用 在与NSOperationQueue一起使用会自动开辟线程进行操作

GDC:
Grand Central Dispatch(GCD)是苹果比较提倡的一个多核编程的解决办法

GCD:底层也是用线程来实现的,知识苹果封装了具体操作的方法,这样可以让程序员不用关注实现的细节只需要专注功能的实现

GCD参数:queue:队列 block任务

GCD 有两种执行任务的方式:
1.同步:dispatch_sync(避免在主队列中使用同步执行主线程任务容易
死锁)

2.异步: dispatch_async

同步和异步的区别:

(1)同步:当前线程中执行
(2)异步:在另一条线程中执行

GCD执行多个任务的<队列>方式 也有两种:

1.串行队列:让一个任务接着一个地执行(一个任务执行完毕后,在执行下一个任务)

2.并发队列:可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效

串行队列有分为两种:
dispatch_get_main_queue()
主队列 串行队列 dispatch_queue_create("", NULL)串行队列
1.主队列 dispatch_get_main_queue( )主队列是GCD自带的一种特殊的串行队列

2.创建一个队列dispatch_queue_creat

并发队列:GCD
/*并发队列: 可以指定队列任务的优先级
使用全局并发队列
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 //

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
默认(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) //

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //
后台

GCD默认已经提供了全局的病发队列,供整个应用使用不需要手动创建 dispatch_get_global_queue

long identifier 指定优先级
*/

dispatch_queue_t firstQueue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0);

dispatch_queue_t secondQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

dispatch_queue_t thirdQueue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(firstQueue, ^{

NSLog(@"11111");
});

dispatch_async(secondQueue, ^{

NSLog(@"22222");
});

dispatch_async(thirdQueue, ^{

NSLog(@"33333");
});

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: