2010-02-15 15 views
11

मैं यूटिलिटीव्यू की कोशिकाओं में यूआरएल से लोड की गई छवियों को कैश करने के तरीके पर ट्यूटोरियल की तलाश कर रहा हूं।कैश यूआरएल छवियां आईफोन यूआईटीबल्यूव्यू

मैं एक उदाहरण यहां

http://www.ericd.net/2009/05/iphone-caching-images-in-memory.html#top

पाया लेकिन कोड अधूरा है। मैं एक उद्देश्य सी नौसिखिया हूं इसलिए मुझे लापता टुकड़ों को भरना बहुत मुश्किल लगता है।

+0

, तुम ग UIImageLoader (https://github.com/gngrwzrd/UIImageLoader) या SDWebImage जैसे सहायक का उपयोग करें। UIImageLoader केवल दो फाइलें और उपयोग करने के लिए सुपर सरल है। रेपो में भी एक अच्छा नमूना है। – gngrwzrd

उत्तर

8

एक अच्छा काम कर रहे उदाहरण यहां मिला था

http://ezekiel.vancouver.wsu.edu/~wayne/yellowjacket/YellowJacket.zip

+4

आईओएस 5: 'गिट क्लोन http: // ezekiel.vancouver.wsu.edu/~ cs458/demos/YellowJackets/.git' [link] (http: //ezekiel.vancouver.wsu) के लिए अद्यतन संस्करण।edu/~ cs458/demos/imageCache/html/image-cache /) – wcochran

0

मैं यह लिखा एक ऐप्लिकेशन मैं पर काम कर रहा है के लिए (अवधारणाओं और कुछ कोड लेन Roathe उत्तम UIImageView + कैश श्रेणी से लिया के साथ)। यह ASIHTTPRequest कक्षाओं का भी उपयोग करता है, जो कि बहुत अच्छे हैं। यह निश्चित रूप से सुधार किया जा सकता है .. उदाहरण के लिए, अनुरोधों को रद्द करने की अनुमति देकर, या अधिसूचना userInfo का उपयोग करके अधिक सटीक UI अद्यतन करने की अनुमति देने के लिए .. लेकिन यह मेरे उद्देश्यों के लिए अच्छा काम कर रहा है।

@implementation ImageFetcher 
#define MAX_CACHED_IMAGES 20 
static NSMutableDictionary* cache = nil; 

+ (void)asyncImageFetch:(UIImage**)anImagePtr withURL:(NSURL*)aUrl { 

    if(!cache) { 
     cache = [[NSMutableDictionary dictionaryWithCapacity:MAX_CACHED_IMAGES] retain]; 
    } 

    UIImage* newImage = [cache objectForKey:aUrl.description]; 
    if(!newImage) { // cache miss - doh! 
     ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:aUrl];  
     imageRequest.userInfo = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:anImagePtr] forKey:@"imagePtr"]; 
     imageRequest.delegate = self; 
     [imageRequest setDidFinishSelector:@selector(didReceiveImage:)]; 
     [imageRequest setDidFailSelector:@selector(didNotReceiveImage:)]; 
     [imageRequest startAsynchronous]; 
    } 
    else { // cache hit - good! 
     *anImagePtr = [newImage retain];  
    } 
} 

+ (void)didReceiveImage:(ASIHTTPRequest *)request { 
    NSLog(@"Image data received."); 
    UIImage **anImagePtr = [(NSValue*)[request.userInfo objectForKey:@"imagePtr"] pointerValue]; 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    UIImage *newImage = [[UIImage imageWithData:[request responseData]] retain]; 

    if(!newImage) { 
     NSLog(@"UIImageView: LoadImage Failed"); 
    } 
    else { 
     *anImagePtr = newImage; 
     // check to see if we should flush existing cached items before adding this new item 
     if([cache count] >= MAX_CACHED_IMAGES) 
      [cache removeAllObjects]; 

     [cache setValue:newImage forKey:[request url].description]; 

     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
     [nc postNotificationName: @"ImageDidLoad" object: self userInfo:request.userInfo]; 
    } 

    [pool drain]; 
} 

आप इस प्रकार इस कोड को फोन: मैं भी सूचनाएं उपयोग कर रहा हूँ बेहतर या बदतर के लिए, के किसी भी मालिकों जाने के लिए

[ImageFetcher asyncImageFetch:&icon withURL:url]; 

इसी UIImage जब वे इस मामले में redisplay- चाहिए , यह एक tableView संदर्भ में बताया गया है:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc addObserver:self selector:@selector(imageDidLoad:) name:@"ImageDidLoad" object:nil]; 
} 

- (void)imageDidLoad:(NSNotification*)notif { 
    NSLog(@"Received icon load notification."); 
    // reload table view so that new image appears.. would be better if I could 
    // only reload the particular UIImageView that holds this image, oh well... 
    [self.tableView reloadData]; 
} 

- (void)dealloc { 
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc removeObserver:self]; 
     // ... 
} 
+0

यहां एक अतिरिक्त युक्ति: यदि आप बहुत सारी छवियों या बड़ी छवियों को कैश कर रहे हैं, और इसलिए स्मृति की एक अच्छी मात्रा का उपयोग कर रहे हैं, तो आप एक बनाना चाहते हैं "+ (शून्य) फ्लश कैश" विधि जो करता है "[कैश हटानेऑल ऑब्जेक्ट्स]" ताकि आप इसे आवश्यक रूप से didReceiveMemory चेतावनी विधियों के भीतर से कॉल कर सकें .. जो उस स्मृति को मुक्त कर देगा। ImageCache.m में –

2

तुम भी यह पूरा करने के enormego पर तेज साथियों द्वारा लिखित भयानक EgoImage लाइब्रेरी का उपयोग कर की कोशिश कर सकते। इसका उपयोग करना बहुत आसान है, दृश्यों के पीछे कैश का कुशल उपयोग करता है और आपकी आवश्यकताओं को पूरा करने के लिए आदर्श रूप से उपयुक्त है।

लाइब्रेरी के लिए github path यहां एक डेमो ऐप शामिल है।

0

आप भी HJCache जांचना चाहेंगे। यह UIImageView संगत दृश्य वर्ग के साथ आता है जो सभी कैशिंग पारदर्शी रूप से करता है और UITableViewCells में उपयोग करने के लिए उपयुक्त है जहां स्क्रॉलिंग प्रदर्शन महत्वपूर्ण है।

35

एनएससीएच का उपयोग करके यहां एक साधारण छवि कैश कार्यान्वयन है। ImageCache एक सिंगलटन है।

ImageCache.h

#import <Foundation/Foundation.h> 

    @interface ImageCache : NSObject 

    @property (nonatomic, retain) NSCache *imgCache; 


    #pragma mark - Methods 

    + (ImageCache*)sharedImageCache; 
    //- (void) AddImage:(NSString *)imageURL: (UIImage *)image; 
    - (void) AddImage:(NSString *)imageURL withImage:(UIImage *)image; 
    - (UIImage*) GetImage:(NSString *)imageURL; 
    - (BOOL) DoesExist:(NSString *)imageURL; 

    @end 

ImageCache.m

#import "ImageCache.h" 

    @implementation ImageCache 

    @synthesize imgCache; 

    #pragma mark - Methods 

    static ImageCache* sharedImageCache = nil; 

    +(ImageCache*)sharedImageCache 
    { 
     @synchronized([ImageCache class]) 
     { 
      if (!sharedImageCache) 
       sharedImageCache= [[self alloc] init]; 

      return sharedImageCache; 
     } 

     return nil; 
    } 

    +(id)alloc 
    { 
     @synchronized([ImageCache class]) 
     { 
      NSAssert(sharedImageCache == nil, @"Attempted to allocate a second instance of a singleton."); 
      sharedImageCache = [super alloc]; 

      return sharedImageCache; 
     } 

     return nil; 
    } 

    -(id)init 
    { 
     self = [super init]; 
     if (self != nil) 
     { 
      imgCache = [[NSCache alloc] init]; 
     } 

     return self; 
    } 

    // - (void) AddImage:(NSString *)imageURL: (UIImage *)image 
- (void) AddImage:(NSString *)imageURL withImage:(UIImage *)image 
    { 
     [imgCache setObject:image forKey:imageURL]; 
    } 

    - (NSString*) GetImage:(NSString *)imageURL 
    { 
     return [imgCache objectForKey:imageURL]; 
    } 

    - (BOOL) DoesExist:(NSString *)imageURL 
    { 
     if ([imgCache objectForKey:imageURL] == nil) 
     { 
      return false; 
     } 

     return true; 
    } 


    @end 

उदाहरण

UIImage *image; 

    // 1. Check the image cache to see if the image already exists. If so, then use it. If not, then download it. 

    if ([[ImageCache sharedImageCache] DoesExist:imgUrl] == true) 
    { 
     image = [[ImageCache sharedImageCache] GetImage:imgUrl]; 
    } 
    else 
    { 
     NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: imgUrl]]; 
     image = [[UIImage alloc] initWithData:imageData]; 

     // Add the image to the cache 
     //[[ImageCache sharedImageCache] AddImage:imgUrl :image]; 

     [[ImageCache sharedImageCache] AddImage:imgUrl withImage:image]; 
    } 
इसके बजाय अपने आप को सब कुछ को लागू करने की
+0

विधि में एक टाइपो है: '- (शून्य) AddImage: (NSString *) imageURL: (NSString *) छवि' होना चाहिए - (शून्य) AddImage: (NSString *) imageURL: (UIImage *) image '। '(एनएसएसटींग *) छवि'' (UIImage *) छवि होना चाहिए। –

+2

यह उत्तर मुझे –

+0

धन्यवाद ऑस्टिन, मैंने कोड तय किया। – Flea

संबंधित मुद्दे