2013-06-26 47 views
8

我想優化我的應用程序中的加載,事實上,我有很多加載在我的應用程序中的圖像,並且我花了很多時間等待視圖控制器打開,特別是包含大量圖像的第一個初始視圖。在後臺加載圖像以優化ios中的加載

我看了看apple sample

,但我不能再工作,整個應用程序,我想只是告訴我具體是什麼,應該怎麼做什麼?我實現?

tableview,其中單元實現cellforrowatindexpath:

NSURL *imageURL = ......; 
NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
UIImage *imageLoad; 
imageLoad = [[UIImage alloc] initWithData:imageData]; 
imageView.image = imageLoad; 

我能做些什麼?

謝謝你的幫助!

enter image description here

+1

的NSData *的imageData = [NSData的dataWithContentsOfURL:IMAGEURL];將需要很長的..異步加載的圖像 –

+0

你可以把它寫爲代碼?請告訴我如何? – CarinaM

回答

3

是的,你可以添加佔位形象吧。

它不會減慢滾動速度,並會隨着時間的推移相應加載圖像。

而且進口這個文件的UIImageView + WebCache.mMapKit框架

Here is the link下載的文件。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
     } 
    UIImageview* iV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)]; 
    [iV setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"image_placeholder.gif"]]; 
    [cell.contentView addSubview:iV]; 
    [iV release]; 

} 

只是清潔,建造和運行。

+1

我會盡力給你一個反饋 – CarinaM

+0

當然..它肯定會工作。 – AtWork

+0

好的,謝謝,明天給我試試吧請 – CarinaM

2

在此控制請看: https://github.com/nicklockwood/AsyncImageView

這是非常容易實現的(僅1個文件),將滿足您的需求就好了。

採用這種控制: 而不是聲明的:

NSURL *imageURL = ......; 
NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
UIImage *imageLoad; 
imageLoad = [[UIImage alloc] initWithData:imageData]; 
imageView.image = imageLoad; 

用途:

NSURL *imageURL = ......; 
imageView.imageURL = imageURL; 
+1

我會嘗試並給予ua反饋 – CarinaM

2

啓用的應用,同時正在從服務器和禁用塊的圖像,同時加載圖像嘗試使用UIImageView + AFNetworking庫以異步方式從服務器加載圖像AFNetworking

NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"]; 

    UIImageView *myImage = [[UIImageView alloc] init]; 

    [myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"PlaceHolder.png"]]; 

只需添加這個庫和包括的UIImageView + AFNetworking這樣你就可以使用新的UIImageView類別imageWithUrl

+0

我會嘗試給予ua反饋 – CarinaM

+0

當我添加庫時,我檢查(將項目複製到目標組中,如果需要的話),但是當我運行它時,出現錯誤:linker command failed with退出代碼1(使用-v來查看調用)......... 應該自己從這個庫創建每個文件嗎?或者有一種方法將其導入到我的應用程序中? – CarinaM

6

試試這個代碼:

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
dispatch_async(q, ^{ 
    /* Fetch the image from the server... */ 
    NSData *data = [NSData dataWithContentsOfURL:url]; 
    UIImage *img = [[UIImage alloc] initWithData:data]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     /* This is the main thread again, where we set the tableView's image to 
     be what we just fetched. */ 
     cell.imgview.image = img; 
    }); 
}); 
+0

我會嘗試並給你一個反饋 – CarinaM

+0

我試過你的解決方案,在一個項目中的圖像查看器。工作正常!只是想添加它,然後也在UITableViewCells中延遲加載縮略圖,並且出現了一個小問題:UIImage * img在調用主線程的塊內不可見。會給它一個研究! – habamedia

+0

我發現了一個簡單的解決方案,使var在主隊列上的其他博客分派中可見。我將添加它作爲一個新的答案,並張貼我編輯的代碼片段。 – habamedia

0

你可以嘗試這樣的事情......! 。

dispatch_queue_t checkInQueueForPostImage = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

         dispatch_async(checkInQueueForPostImage, ^{ 
          UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:postAndCheckInDetails.postImageURL]]]; 

          dispatch_sync(dispatch_get_main_queue(), ^{ 
           if (image!=nil) { 
            [uploadImage setImage:image]; 
           } 

           [cell setNeedsLayout]; 
          }); 
         }); 
+0

我會嘗試並給你一個反饋 – CarinaM

0

您可以使用異步imageview。

- (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key { 
    self.imageURL = url; 
    self.image = placeholder; 

    NSData *cachedData = [FTWCache objectForKey:key]; 
    if (cachedData) { 
     self.imageURL = nil; 
     self.image  = [UIImage imageWithData:cachedData]; 
     return; 
    } 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSData *data = [NSData dataWithContentsOfURL:url]; 

     UIImage *imageFromData = [UIImage imageWithData:data]; 

     [FTWCache setObject:data forKey:key]; 

     if (imageFromData) { 
      if ([self.imageURL.absoluteString isEqualToString:url.absoluteString]) { 
       dispatch_sync(dispatch_get_main_queue(), ^{ 
        self.image = imageFromData; 
       }); 
      } else { 
//    NSLog(@"urls are not the same, bailing out!"); 
      } 
     } 
     self.imageURL = nil; 
    }); 
} 

看看this link。你會對使用異步imageview有一個想法。

+1

我會盡力給你一個反饋 – CarinaM

2

你可以查看本教程NSOperationQueueGCD這個完全相同。你也可以嘗試使用:

// Block variable to be assigned in block. 
__block NSData *imageData; 
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL); 

// Dispatch a background thread for download 
dispatch_async(backgroundQueue, ^(void) { 
    imageData = [NSData dataWithContentsOfURL:imageURL]; 
    UIImage *imageLoad; 
    imageLoad = [[UIImage alloc] initWithData:imageData]; 

    // Update UI on main thread 
    dispatch_async(dispatch_get_main_queue(), ^(void) { 
     imageView.image = imageLoad; 
    }); 
}); 
+1

我會盡力給你一個反饋 – CarinaM

0

這是一個略有修改的方法拉穆Pasupoletis答案。我添加了 __block 修飾符,使var img在主線程中調用的塊內可見。這裏是我在

中使用的完整方法定義
-(UITableViewCell*)cellforRowAtIndexPath:(UIIndexPath*)indexPath; 

用於緩慢提取縮略圖。我還爲單元格UIImageViews添加了佔位符。

//lazy loading of thumbnails for images in cell via bg thread 
-(void)loadImageForCell:(CustomEditTableViewCell*)theCell withFilepath: (NSString*)filepath{ 

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
dispatch_async(q, ^{ 
    UIImage (__block *img) = [UIImage imageWithContentsOfFile:filepath]; 
    UIImage *thumbnail = [[GlobalFunctions sharedGlobalFunctions] imageOfSize:CGSizeMake(40, 40) fromImage:img]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     theCell.imageView.image = thumbnail; 
    }); 
}); 
} 
0

使用IDAsyncImageView.h

////////////////////////////////////// 
    IDAsyncImageView.h 
///////////////////////////////////// 

     @interface IDAsyncImageView : NSObject 

     @property (nonatomic, strong) NSCache *cache;  

     + (instancetype)instance; 

     - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString; 

     @end 

    ////////////////////////////////////// 
    IDAsyncImageView.m 
    ///////////////////////////////////// 

     #import "IDAsyncImageView.h" 



      @implementation IDAsyncImageView 

       + (instancetype)instance 
       { 
        static IDAsyncImageView *_instance = nil; 
        static dispatch_once_t onceToken; 
        dispatch_once(&onceToken, ^{ 
         _instance = [[self alloc] init]; 
       }); 
       return _instance; 
      } 

     - (instancetype)init 
     { 
      self = [super init]; 
      if (self) { 
       self.cache = [[NSCache alloc] init]; 
      } 

      return self; 
     } 

     - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString 
     { 
      UIActivityIndicatorView* activityView; 
      activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      activityView.hidesWhenStopped = YES; 
      activityView.center = CGPointMake(imageView.bounds.size.width/2.0f, imageView.bounds.size.height/2.0f); 
      activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; 
      [imageView addSubview:activityView]; 
      [activityView startAnimating]; 

      UIImage* imageLoad = [self.cache objectForKey:urlString]; 
      if (nil != imageLoad) { 
       imageView.image = imageLoad; 
       [activityView removeFromSuperview]; 
      } 
      else { 

      // Block variable to be assigned in block. 
      __block NSData *imageData; 

      // Dispatch a background thread for download 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
       imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; 
       UIImage* imageLoad = [[UIImage alloc] initWithData:imageData]; 

       // Update UI on main thread 
       dispatch_async(dispatch_get_main_queue(), ^(void) { 
        [self.cache setObject:imageLoad forKey:urlString]; 
        imageView.image = imageLoad; 
        [activityView removeFromSuperview]; 
       }); 
      }); 
      } 
     } 

    ////////////////////////////////////// 
    ViewController.m 
    ////////////////////////////////////// 

     - (void)viewDidLoad { 
     [super viewDidLoad]; 
     [[IDAsyncImageView instance] loadImageView:myImageView withURLString:aUrl]; 
     }