1、完成一個簡略的tableView顯示後果
完成後果展現:
代碼示例(應用之前在主掌握器中停止營業處置的方法)
1.新建一個項目,讓掌握器繼續自UITableViewController。
//
// YYViewController.h
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface YYViewController : UITableViewController
@end
2.處置storyboard中得界面,以下:
3.依據plist文件,字典轉模子
新建一個類,繼續自NSObject,作為數據的模子
YYappModel.h文件
//
// YYappModel.h
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface YYappModel : NSObject
/**
*運用稱號
*/
@property(nonatomic,copy)NSString *name;
/**
* 運用圖片
*/
@property(nonatomic,copy)NSString *icon;
/**
* 運用的下載量
*/
@property(nonatomic,copy)NSString *download;
+(instancetype)appModelWithDict:(NSDictionary *)dict;
-(instancetype)initWithDict:(NSDictionary *)dict;
@end
YYappModel.m文件
//
// YYappModel.m
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYappModel.h"
@implementation YYappModel
-(instancetype)initWithDict:(NSDictionary *)dict
{
if (self=[super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
//工場辦法
+(instancetype)appModelWithDict:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
@end
主掌握器中得邏輯掌握部門,YYViewController.m文件
//
// YYViewController.m
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappModel.h"
@interface YYViewController ()
@property(nonatomic,strong)NSArray *apps;
@end
@implementation YYViewController
#pragma mark- 懶加載
-(NSArray *)apps
{
if (_apps==nil) {
NSString *path=[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];
NSArray *tempArray=[NSArray arrayWithContentsOfFile:path];
//字典轉模子
NSMutableArray *array=[NSMutableArray array];
for (NSDictionary *dict in tempArray) {
YYappModel *app=[YYappModel appModelWithDict:dict];
[array addObject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-數據源辦法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.apps.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID=@"ID";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
YYappModel *app=self.apps[indexPath.row];
cell.textLabel.text=app.name;
cell.detailTextLabel.text=app.download;
//下載圖片數據
NSLog(@"加載圖片數據---%@", [NSThread currentThread]);
NSURL *url=[NSURL URLWithString:app.icon];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *imgae=[UIImage imageWithData:data];
cell.imageView.image=imgae;
NSLog(@"完成顯示");
return cell;
}
@end
打印檢查:
2、自界說NSOperation
解釋:下面的下載圖片數據部門是一個異常耗時的操作,這個操作義務在主線程完成,會嚴重的影響到用戶體驗,形成UI卡的景象。上面經由過程自界說NSOperation,新開線程,讓加載圖片的義務異步履行。
1.經由過程署理
在下面的基本上,新建一個類,讓其繼續自NSOperation。
YYdownLoadOperation.h文件
//
// YYdownLoadOperation.h
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
#pragma mark-設置署理和署理辦法
@class YYdownLoadOperation;
@protocol YYdownLoadOperationDelegate <NSObject>
-(void)downLoadOperation:(YYdownLoadOperation*)operation didFishedDownLoad:(UIImage *)image;
@end
@interface YYdownLoadOperation : NSOperation
@property(nonatomic,copy)NSString *url;
@property(nonatomic,strong)NSIndexPath *indexPath;
@property(nonatomic,strong)id <YYdownLoadOperationDelegate> delegate;
@end
YYdownLoadOperation.m文件
//
// YYdownLoadOperation.m
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYdownLoadOperation.h"
@implementation YYdownLoadOperation
-(void)main
{
NSURL *url=[NSURL URLWithString:self.url];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *imgae=[UIImage imageWithData:data];
NSLog(@"--%@--",[NSThread currentThread]);
//圖片下載終了後,告訴署理
if ([self.delegate respondsToSelector:@selector(downLoadOperation:didFishedDownLoad:)]) {
dispatch_async(dispatch_get_main_queue(), ^{//回到主線程,傳遞數據給署理對象
[self.delegate downLoadOperation:self didFishedDownLoad:imgae];
});
}
}
@end
主掌握器中的營業邏輯:
//
// YYViewController.m
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappModel.h"
#import "YYdownLoadOperation.h"
@interface YYViewController ()<YYdownLoadOperationDelegate>
@property(nonatomic,strong)NSArray *apps;
@property(nonatomic,strong)NSOperationQueue *queue;
@end
@implementation YYViewController
#pragma mark- 懶加載apps
-(NSArray *)apps
{
if (_apps==nil) {
NSString *path=[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];
NSArray *tempArray=[NSArray arrayWithContentsOfFile:path];
//字典轉模子
NSMutableArray *array=[NSMutableArray array];
for (NSDictionary *dict in tempArray) {
YYappModel *app=[YYappModel appModelWithDict:dict];
[array addObject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-懶加載queue
-(NSOperationQueue *)queue
{
if (_queue==Nil) {
_queue=[[NSOperationQueue alloc]init];
//設置最年夜並發數為3
_queue.maxConcurrentOperationCount=3;
}
return _queue;
}
#pragma mark-數據源辦法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.apps.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID=@"ID";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
YYappModel *app=self.apps[indexPath.row];
cell.textLabel.text=app.name;
cell.detailTextLabel.text=app.download;
//下載圖片數據
// NSLog(@"加載圖片數據---%@", [NSThread currentThread]);
// NSURL *url=[NSURL URLWithString:app.icon];
// NSData *data=[NSData dataWithContentsOfURL:url];
// UIImage *imgae=[UIImage imageWithData:data];
// cell.imageView.image=imgae;
//創立一個OPeration對象
YYdownLoadOperation *operation=[[YYdownLoadOperation alloc]init];
operation.url=app.icon;
operation.indexPath=indexPath;
operation.delegate=self;
//把操尴尬刁難象添加到隊列中在去
[self.queue addOperation:operation];
// NSLog(@"完成顯示");
return cell;
}
-(void)downLoadOperation:(YYdownLoadOperation *)operation didFishedDownLoad:(UIImage *)image
{
//前往圖片數據給每行對應的cell的imageview.image
//掏出tableview中indexPath這一行對應的cell
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:operation.indexPath];
//顯示圖片
cell.imageView.image=image;
// NSLog(@"cell--index--%@---%@",operation.indexPath,[NSThread currentThread]);
//必定要刷新表格
[self.tableView reloadData];
NSLog(@"--%@--",[NSThread currentThread]);
}
@end
解釋:經由過程打印可以發明下面的代碼存在很年夜的成績。
成績1:須要包管一個url對應一個operation對象。
成績2:下載完須要移除。移除履行終了的操作。
成績3:包管一個url對應一個image。
上面對主掌握器中得代碼停止改良:
//
// YYViewController.m
// 01-自界說Operation
//
// Created by apple on 14-6-26.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
#import "YYappModel.h"
#import "YYdownLoadOperation.h"
@interface YYViewController ()<YYdownLoadOperationDelegate>
@property(nonatomic,strong)NSArray *apps;
@property(nonatomic,strong)NSOperationQueue *queue;
@property(nonatomic,strong)NSMutableDictionary *operations;
@property(nonatomic,strong)NSMutableDictionary *images;
@end
@implementation YYViewController
#pragma mark- 懶加載apps
-(NSArray *)apps
{
if (_apps==nil) {
NSString *path=[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];
NSArray *tempArray=[NSArray arrayWithContentsOfFile:path];
//字典轉模子
NSMutableArray *array=[NSMutableArray array];
for (NSDictionary *dict in tempArray) {
YYappModel *app=[YYappModel appModelWithDict:dict];
[array addObject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-懶加載queue
-(NSOperationQueue *)queue
{
if (_queue==Nil) {
_queue=[[NSOperationQueue alloc]init];
//設置最年夜並發數為3
_queue.maxConcurrentOperationCount=3;
}
return _queue;
}
#pragma mark-懶加載operations
-(NSMutableDictionary *)operations
{
if (_operations==Nil) {
_operations=[NSMutableDictionary dictionary];
}
return _operations;
}
#pragma mark-懶加載images
-(NSMutableDictionary *)images
{
if (_images==Nil) {
_images=[NSMutableDictionary dictionary];
}
return _images;
}
#pragma mark-數據源辦法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.apps.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID=@"ID";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
YYappModel *app=self.apps[indexPath.row];
cell.textLabel.text=app.name;
cell.detailTextLabel.text=app.download;
//包管一個url對應一個image對象
UIImage *image=self.images[app.icon];
if (image) {//緩存中有圖片
cell.imageView.image=image;
}else // 緩存中沒有圖片,得下載
{
//先設置一張占位圖片
cell.imageView.image=[UIImage imageNamed:@"57437179_42489b0"];
YYdownLoadOperation *operation=self.operations[app.icon];
if (operation) {//正鄙人載
//甚麼都不做
}else //以後沒有下載,那就創立操作
{
operation=[[YYdownLoadOperation alloc]init];
operation.url=app.icon;
operation.indexPath=indexPath;
operation.delegate=self;
[self.queue addOperation:operation];//異步下載
self.operations[app.icon]=operation;
}
}
return cell;
}
-(void)downLoadOperation:(YYdownLoadOperation *)operation didFishedDownLoad:(UIImage *)image
{
//1.移除履行終了的操作
[self.operations removeObjectForKey:operation.url];
//2.將圖片放到緩存中
self.images[operation.url]=image;
//3.刷新表格(只刷新下載的那一行)
[self.tableView reloadRowsAtIndexPaths:@[operation.indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
NSLog(@"--%d--%@--",operation.indexPath.row,[NSThread currentThread]);
}
@end
打印檢查:
【iOS多線程運用開辟中自界說NSOperation類的實例解析】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!