First, to achieve a simple tableview display effect
Implementation results show:
code example (using the previous business process in the host controller)
1. Create a new project and let the controller inherit from Uitableviewcontroller.
Copy Code code as follows:
//
YYViewController.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface Yyviewcontroller:uitableviewcontroller
@end
2. Processing storyboard interface, as follows:
3. According to the plist file, the dictionary turns the model
Create a new class that inherits from NSObject as a model of the data
YYappModel.h file
Copy Code code as follows:
//
YYappModel.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Yyappmodel:nsobject
/**
* Application Name
*/
@property (nonatomic,copy) NSString *name;
/**
* Application Picture
*/
@property (nonatomic,copy) NSString *icon;
/**
* Download amount of Application
*/
@property (nonatomic,copy) NSString *download;
+ (Instancetype) appmodelwithdict: (Nsdictionary *) dict;
-(Instancetype) Initwithdict: (Nsdictionary *) dict;
@end
YYAPPMODEL.M file
Copy Code code as follows:
//
yyappmodel.m
01-Custom 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;
}
Factory method
+ (Instancetype) appmodelwithdict: (Nsdictionary *) dict
{
return [[Self alloc]initwithdict:dict];
}
@end
Logical control part of the main controller, YYVIEWCONTROLLER.M file
Copy Code code as follows:
//
Yyviewcontroller.m
01-Custom 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
Copy Code code as follows:
@implementation Yyviewcontroller
#pragma mark-lazy Load
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];
Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-Data source method
-(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;
Download picture data
NSLog (@ "Load picture data---%@", [Nsthread CurrentThread]);
Nsurl *url=[nsurl URLWithString:app.icon];
NSData *data=[nsdata Datawithcontentsofurl:url];
UIImage *imgae=[uiimage Imagewithdata:data];
Cell.imageview.image=imgae;
NSLog (@ "complete display");
return cell;
}
@end
Print View:
Ii. Custom Nsoperation
Description: The above download picture data section is a very time-consuming operation, this operation task in the main thread complete, will seriously affect the user experience, resulting in UI card phenomenon. The following custom nsoperation, a new thread, lets the task that loads the picture execute asynchronously.
1. By proxy
Based on the above, create a new class that inherits from Nsoperation.
YYdownLoadOperation.h file
Copy Code code as follows:
//
YYdownLoadOperation.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//
#import <Foundation/Foundation.h>
#pragma mark-set agent and proxy methods
@class yydownloadoperation;
@protocol yydownloadoperationdelegate <NSObject>
-(void) Downloadoperation: (yydownloadoperation*) Operation Didfisheddownload: (UIImage *) image;
@end
Copy Code code as follows:
@interface yydownloadoperation:nsoperation
@property (nonatomic,copy) NSString *url;
@property (Nonatomic,strong) Nsindexpath *indexpath;
@property (nonatomic,strong) ID <YYdownLoadOperationDelegate> delegate;
@end
YYDOWNLOADOPERATION.M file
Copy Code code as follows:
//
Yydownloadoperation.m
01-Custom 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]);
After downloading the picture, notify the agent
if ([Self.delegate respondstoselector: @selector (downloadoperation:didfisheddownload:)]) {
Dispatch_async (Dispatch_get_main_queue (), ^{//back to the main thread, passing data to the proxy object
[Self.delegate downloadoperation:self Didfisheddownload:imgae];
});
}
}
@end
Business logic in the Master controller:
Copy Code code as follows:
//
Yyviewcontroller.m
01-Custom 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
Copy Code code as follows:
@implementation Yyviewcontroller
#pragma mark-lazy load apps
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];
Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-lazy load queue
-(Nsoperationqueue *) queue
{
if (_queue==nil) {
_queue=[[nsoperationqueue Alloc]init];
Set the maximum concurrency number to 3
_queue.maxconcurrentoperationcount=3;
}
return _queue;
}
#pragma mark-Data source method
-(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;
Download picture data
NSLog (@ "Load picture data---%@", [Nsthread CurrentThread]);
Nsurl *url=[nsurl URLWithString:app.icon];
NSData *data=[nsdata Datawithcontentsofurl:url];
UIImage *imgae=[uiimage Imagewithdata:data];
Cell.imageview.image=imgae;
Create a Operation object
Yydownloadoperation *operation=[[yydownloadoperation Alloc]init];
Operation.url=app.icon;
Operation.indexpath=indexpath;
operation.delegate=self;
Add the Action object to the queue.
[Self.queue addoperation:operation];
NSLog (@ "complete display");
return cell;
}
-(void) Downloadoperation: (yydownloadoperation *) operation Didfisheddownload: (UIImage *) image
{
Returns the imageview.image of the cell corresponding to each row of the image data
Remove the cell corresponding to the Indexpath line in the TableView
UITableViewCell *cell=[self.tableview CellForRowAtIndexPath:operation.indexPath];
Show pictures
Cell.imageview.image=image;
NSLog (@ "cell--index--%@---%@", operation.indexpath,[nsthread CurrentThread]);
Be sure to refresh the table
[Self.tableview Reloaddata];
NSLog (@ "--%@--", [Nsthread CurrentThread]);
}
@end
Note: By printing you can find that the above code has a big problem.
Issue 1: You need to ensure that a URL corresponds to a Operation object.
Question 2: Remove the download. Removes the completed operation.
Question 3: Ensure that a URL corresponds to an image.
The following improvements are made to the code in the master controller:
Copy Code code as follows:
//
Yyviewcontroller.m
01-Custom 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
Copy Code code as follows:
@implementation Yyviewcontroller
#pragma mark-lazy load apps
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];
Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}
#pragma mark-lazy load queue
-(Nsoperationqueue *) queue
{
if (_queue==nil) {
_queue=[[nsoperationqueue Alloc]init];
Set the maximum concurrency number to 3
_queue.maxconcurrentoperationcount=3;
}
return _queue;
}
#pragma mark-lazy load operations
-(Nsmutabledictionary *) operations
{
if (_operations==nil) {
_operations=[nsmutabledictionary dictionary];
}
return _operations;
}
#pragma mark-lazy load images
-(Nsmutabledictionary *) images
{
if (_images==nil) {
_images=[nsmutabledictionary dictionary];
}
return _images;
}
#pragma mark-Data source method
-(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;
Ensure that a URL corresponds to an image object
UIImage *image=self.images[app.icon];
if (image) {//There is a picture in the cache
Cell.imageview.image=image;
No pictures in}else//cache, download
{
Set up a placeholder picture first
Cell.imageview.image=[uiimage imagenamed:@ "57437179_42489b0"];
Yydownloadoperation *operation=self.operations[app.icon];
if (operation) {//is downloading
Don't do anything.
}else//Not currently downloaded, create action
{
Operation=[[yydownloadoperation Alloc]init];
Operation.url=app.icon;
Operation.indexpath=indexpath;
operation.delegate=self;
[Self.queue addoperation:operation];//Asynchronous download
Self.operations[app.icon]=operation;
}
}
return cell;
}
-(void) Downloadoperation: (yydownloadoperation *) operation Didfisheddownload: (UIImage *) image
{
1. Remove the completed operation
[Self.operations RemoveObjectForKey:operation.url];
2. Put the picture in the cache
Self.images[operation.url]=image;
3. Refresh the table (refresh only the downloaded line)
[Self.tableview Reloadrowsatindexpaths:@[operation.indexpath] withrowanimation:uitableviewrowanimationautomatic] ;
NSLog (@ "--%d--%@--", Operation.indexpath.row,[nsthread CurrentThread]);
}
@end
Print View: