본문 바로가기

프로그램/iPhone

이미지캐쉬 사용하기

아이폰 앱 개발을 할 때, 배경/아이콘/버튼 등에 이미지를 사용하는 경우가 빈번하다. 그런데 동일한 이미지를 여러 곳에서 사용할 경우에는 이미지 캐시를 사용하여, 동일한 이미지가 여러 번 로딩되어 불필요한 메모리 사용이나 IO 사용을 막는 것이 중요하다. 그렇지 않아도 적은 메모리 안에서 앱을 실행시켜야 하니까... 

본 포스트와 동일한 내용(이미지 캐시)을 담고 있는 Image Cache라는 포스트를 이전에 작성했었다. 구현 방법은 딕셔너리를 이용하여 한 번 사용했던 이미지를 재사용하는 방법 이었다. 이번에는 같은 목적을 위해, 싱글톤을 이용한다.

우선 사용방법부터 설명하면 다음과 같다.

UIImageView *backgroundImage = nil;

...

[backgroundImage setImage:[[ImageCache sharedInstanceimageNamed:@"backgroundImage.png"]];


이렇게 하기 위해, 다음 예와 같이 LPImageCache 클래스를 작성한다. 그러나 이미지 캐시를 사용할 때 가장 중요한 것은 iOS로부터 메모리 경고를 받았을 경우 캐시를 삭제하는 것이다. 그리고 싱글톤을 사용하기 위해 이전에 소개했던 SynthesizeSingleton.h(SYNTHESIZE_SINGLETON_FOR_CLASS 매크로 소개)를 사용해도 좋다.

[LPImageCache.h]

#import <UIKit/UIKit.h>



@interface LPImageCache : NSObject {

NSMutableDictionary *cache;

}


#pragma mark Instance methods

- (UIImage *) imageNamed:(NSString *)imageNamed;

#pragma mark -


#pragma mark Singleton methods

+ (LPImageCache *)sharedInstance;

#pragma mark -


@end


[LPImageCache.m]

#import "LPImageCache.h"


static LPImageCache *sharedInstance = nil;


@implementation LPImageCache


#pragma mark -

#pragma mark 인스턴스 메서드


- (id) init {

self = [super init];

if (self != nil) {

cache = [NSMutableDictionary new];

}

return self;

}



- (UIImage *)imageNamed:(NSString *)imageNamed {

UIImage *image = [cache objectForKey:imageNamed];

if (image == nil) {

image = [UIImage imageNamed:imageNamed];

[cache setObject:image forKey:imageNamed]; 

}

return image;

}



#pragma mark -

#pragma mark  싱글톤 메서드들


+ (LPImageCache *)sharedInstance {

    @synchronized(self) {

        if (sharedInstance == nil) {

sharedInstance = [[ImageCache allocinit];

}

    }

    return sharedInstance;

}



+ (id)allocWithZone:(NSZone *)zone {

    @synchronized(self) {

        if (sharedInstance == nil) {

            sharedInstance = [super allocWithZone:zone];

            return sharedInstance;  

        }

    }

    return nil

}



- (id)copyWithZone:(NSZone *)zone {

    return self;

}



- (id)retain {

    return self;

}



- (unsigned)retainCount {

    // 릴리즈   없는 객체를 기록.

    return UINT_MAX;

}



- (void)release {


}



- (id)autorelease {

    return self;

}


@end




출처 : http://lambert.tistory.com/396