2010년 8월 10일 화요일

[iPhone] UIImage에 imageNamed

UIImage에 imageNamed Method (http://cafe.naver.com/mcbugi/71591)

UIImage의 imageNamed의 특징은 단순히 이름으로 파일을 열어서 이미지를 불러오지만 캐싱한다는 점이 있습니다. 이 캐싱은 장단점이 있습니다.


문제는 한번 로드하면 해제를 안합니다.


본문을 캡쳐 해 온 것인데.. imageNamed는 한번 로드하면 (어플이 죽기 전까지) 해제를 하지 않는 다는게
큰 문제지요.. 뭐.. 데스크탑이라면 전혀 문제 될것이 없지만.. 모바일 기기에는 한정이 되어 있는 메모리가 있으므로.. 문제가 되지요. (느려진다거나 메모리 부족으로 죽는다는 현상)

그래서.. 친절한 문씨님께서는.. 해결책도 적어 두셨습니다.

//UIImageExtension.h

@interface UIImage (UIImageExtension)

+ (UIImage *)imageNamed:(NSString *)name forSession:(id)session;

+ (void)clearSession:(id)session;

@end


헤더에는 이것뿐입니다. 다른 함수는 알 필요가 없죠


//UIImageExtension.m

#import “UIImageExtension.h”


@implementation UIImage (UIImageExtension)

static NSMutableDictionary *__imageSessions;


+ (NSMutableDictionary *)_imageSessions {

        if (__imageSessions == nil) {

            __imageSessions = [[NSMutableDictionary alloc] init];

        }

        return __imageSessions;

}


+ (NSMutableDictionary *)_sessionForKey:(NSString *)key {

        NSMutableDictionary *data = [self _imageSessions];

        NSMutableDictionary *session = [data objectForKey:key];

        if (session == nil) {

                session = [NSMutableDictionary dictionary];

                [data setObject:session forKey:key];

        }

        return session;

}

+ (UIImage *)_findImageWithName:(NSString *)name {

        NSArray *sessionKeys = [__imageSessions allKeys];

        UIImage *image = nil;

        for (int i = 0; i < [sessionKeys count] && image == nil; i++) {

                NSMutableDictionary *session = [__imageSessions objectForKey:[sessionKeys objectAtIndex:i]];

                image = [session objectForKey:name];

        }

        return image;

}


+ (UIImage *)imageNamed:(NSString *)name forSession:(id)session {

        NSString *key = [NSString stringWithFormat:@”%p”,session];


        NSMutableDictionary *sessionContainer = [self _sessionForKey:key];


        UIImage *image = [sessionContainer objectForKey:name];


        if (image != nil) {

                return image;

        } else {

                image = [self _findImageWithName:name]; //다른곳에 등록된 이미지를 찾는다


                if (image == nil) {

                        NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:nil];

                        if (path != nil) {

                                image = [UIImage imageWithContentsOfFile:path];                                

                        }

                }

                if (image != nil) {

                         [sessionContainer setObject:image forKey:name];

                }


        }

        return image;

}


+ (void)clearSession:(id)session {

        if (session == nil) return;

        NSString *key = [NSString stringWithFormat:@”%p”,session];

        [__imageSessions removeObjectForKey:key];

}


@end

[출처] [문씨의 강좌adkf] 메모리 관리3 <Singleton> (맥부기 아이폰(iPhone)OS 개발자모임) |작성자 문씨


위와 같은 Category를 만들어서 사용한다면.. 조금이나마 메모리 관리를 효율 적으로 할 수 있지 않을까?

0 개의 댓글:

댓글 쓰기