IOS development practices-cell download image (custom NSOperation)

Source: Internet
Author: User

IOS development practices-cell download image (custom NSOperation)

The image downloading operations in the previous article are all placed in blocks. When complicated operations are encountered, a bunch of code is put in blocks. Obviously, this is not a wise choice, and the code looks bloated. Therefore, place thread operations in custom NSOperation.

Step for customizing NSOperation: Inherit NSOperation and override-(void) main method to implement the task you want to execute.

Note the following when rewriting the (void) main method:

1. Create an automatic release pool on your own (because the automatic release pool of the main thread cannot be accessed for asynchronous operations ).

2. Use the-(BOOL) isCancelled method to check whether the operation is canceled and respond to the cancellation.

Case code:

1. Create DownloadOperation to inherit NSOperation, and put the download operation in the main method. As for what to do after the download is returned to the main thread, it itself does not know (not its scope of work ). It is only responsible for notifying other people after the download is completed. Therefore, it is responsible for entrusting agents to others to do things.

DownloadOperation. h

# Import
 
  
# Import
  
   
@ Class DownloadOperation; // protocol @ protocol DownloadOperationDelegate
   
    
@ Optional-(void) downloadOperation :( DownloadOperation *) operation didFinishDownload :( UIImage *) image; @ end @ interface DownloadOperation: NSOperation // download image address @ property (nonatomic, copy) NSString * imageUrl; // table cell location @ property (nonatomic, strong) NSIndexPath * indexPath; // proxy @ property (nonatomic, weak) id
    
     
Delegate; @ end
    
   
  
 

DownloadOperation. m

Note: @ autoreleasepool Automatically releases the pool and the isCancelled method checks whether the operation is canceled and responds to the cancellation.

# Import "DownloadOperation. h" # import
 
  
@ Implementation DownloadOperation-(void) main {@ autoreleasepool {// manage the memory if (self. isCancelled) return; // The NSURL * url = [NSURL URLWithString: self. imageUrl]; NSData * data = [NSData dataWithContentsOfURL: url]; // download UIImage * image = [UIImage imageWithData: data]; // NSData-> UIImage if (self. isCancelled) return; // pause the ongoing operation // return to the main thread [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {if ([self. delegate respondsToSelector: @ selector (downloadOperation: didFinishDownload :)]) {[self. delegate downloadOperation: self didFinishDownload: image] ;}}] ;}@ end
 

2. AppsTableViewController. m

//// AppsTableViewController. m // cell image download (custom operation) # import "AppsTableViewController. h "# import" App. h "# import" DownloadOperation. h "@ interface AppsTableViewController ()
 
  
// Application information set @ property (nonatomic, strong) NSMutableArray * apps; // queue for storing all downloaded images @ property (nonatomic, strong) NSOperationQueue * queue; // store all download operations (the url is key and the operation object is value) @ property (nonatomic, strong) NSMutableDictionary * operations; // store all downloaded images @ property (nonatomic, strong) NSMutableDictionary * images; @ end @ implementation AppsTableViewController-(void) viewDidLoad {[super viewDidLoad];}-(void) didReceiveMemoryWa Rning {[super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}/*** load lazily **/-(NSMutableArray *) apps {if (! _ Apps) {NSMutableArray * appArr = [NSMutableArray array]; NSString * file = [[NSBundle mainBundle] pathForResource: @ "apps" ofType: @ "plist"]; NSArray * dictArr = [NSArray arrayWithContentsOfFile: file]; for (NSDictionary * dict in dictArr) {App * app = [App appWithDict: dict]; [appArr addObject: app];} _ apps = appArr;} return _ apps;}-(NSOperationQueue *) queue {if (! _ Queue) {_ queue = [[NSOperationQueue alloc] init];} return _ queue;}-(NSMutableDictionary *) operations {if (! _ Operations) {_ operations = [[NSMutableDictionary alloc] init];} return _ operations;}-(NSMutableDictionary *) images {if (! _ Images) {_ images = [[NSMutableDictionary alloc] init];} return _ images;} # pragma mark-Table view data source-(NSInteger) numberOfSectionsInTableView :( UITableView *) tableView {return 1;}-(NSInteger) tableView :( UITableView *) tableView numberOfRowsInSection :( NSInteger) section {return self. apps. count;}-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) inde XPath {static NSString * ID = @ "app"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: ID]; if (! Cell) {cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: ID];} App * app = self. apps [indexPath. row]; cell. textLabel. text = app. name; cell. detailTextLabel. text = app. download; // obtain the UIImage * image = self from the images cache. images [app. icon]; if (image) {// indicates that the image has been downloaded (cached successfully) cell. imageView. image = image;} else {// obtain the caches path. splice the file path NSString * file = [[NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: [app. icon lastPathComponent]; // retrieve the image NSData * data = [NSData dataWithContentsOfFile: file] From the sandbox first; if (data) {// The image cell exists in the sandbox. imageView. image = [UIImage imageWithData: data];} else {// the sandbox is not saved. Download the image and display the cell of the placeholder image. imageView. image = [UIImage imageNamed: @ "placeholder"]; // download the image [self download: app. icon indexPath: indexPath] ;}} return cell;}-(void) download :( NSString *) imageUrl indexPath :( NSIndexPath *) indexPath {// download the DownloadOperation * operation = self. operations [imageUrl]; if (operation) return; // if an operation exists, it will not be executed (because the image download operation may be in progress) // create an operation, download image operation = [[DownloadOperation alloc] init]; operation. imageUrl = imageUrl; operation. indexPath = indexPath; // sets the proxy operation. delegate = self; // Add the operation to the queue [self. queue addOperation: operation]; // Add it to the dictionary (this code is used to solve repeated downloads) self. operations [imageUrl] = operation;}/*** call */-(void) scrollViewWillBeginDecelerating (UIScrollView *) scrollView {// pause the download [self. queue setsuincluded: YES];}/*** call */-(void) scrollViewDidEndDecelerating (UIScrollView *) scrollView {// start to download [self. queue setsuincluded: NO] ;}# pragma mark-proxy method for the download operation-(void) downloadOperation :( DownloadOperation *) operation didFinishDownload :( UIImage *) image {// store the image to the dictionary if (image) {// store all download operations self. operations [operation. imageUrl] = image; // Save the image to the sandbox NSData * data = UIImagePNGRepresentation (image); NSString * file = [NSSearchPathForDirectoriesInDomains achesdirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: [operation. imageUrl lastPathComponent]; [data writeToFile: file atomically: YES];} // remove the download operation from the dictionary (to prevent increasing operations, ensure that the download can be downloaded again after the download fails) [self. operations removeObjectForKey: operation. imageUrl]; // refresh the table [self. tableView reloadRowsAtIndexPaths: @ [operation. indexPath] withRowAnimation: UITableViewRowAnimationNone];} @ end
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.