코코아 애니메이션 예제

코코아 애니메이션 예제

코코아 애니메이션을 사용하여 창의 투명도를 변화시키는 예제. 애플 개발자 문서에서 구할 수 있다. 주요내용은 마우스가 들어오면 불투명해지고 마우스가 나가면 몇 초 후부터 서서히 투명해져 10%까지 투명해지는 창을 만든다.

창의 제어를 위해서 NSWindowController를 사용하고 있으며, NSTrackingArea를 사용하고 있다.

//마우스가 들어오면 불투명하고, 마우스가 나가면 약간의 딜레이 후 투명해지는 애니메이션을 구현한다. 

// InspectorController.h

#import <Cocoa/Cocoa.h>
@interface InspectorController : NSWindowController {
    NSTimer *fadeTimer;
}
@end
// InspectorController.m

#import "InspectorController.h"

@implementation InspectorController

-(id)init {
    self = [super initWithWindowNibName:@"Inspector"]; // Inspector.xib 파일이 있어야 한다.
    return self;
}

-(void)dealloc {
    fadeTimer = nil;
    // ARC 환경에서 [super dealloc]은 부를 수 없다.
}

-(void)setFadeTimer:(NSTimer*)timer
{
    if (fadeTimer != timer) {
        [fadeTimer invalidate];
        fadeTimer = timer;
    }
}

// 윈도우가 로드되면 트랙킹 영역을 추가해서 마우스가 들어오고 나가는 것을 잡는다.
-(void)windowDidLoad {
    NSView *containingView = [[[self window] contentView] superView];
    NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[containingView frame] options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp | NSTrackingInVisibleRect owner:self userInfo:nil];
    [containingView addTrackingArea:area];

    // 타이머를 추가해서 4초 후에 페이딩이 시작되도록 한다.
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(startFade:) userInfo:nil repeats:NO];
    self setFadeTimer = timer;
}

-(void)mouseEntered:(NSEvent*)event {
    [self setFadeTimer:nil];
    [[[self window] animator] setAlphaValue:1.0];
}

-(void)mouseExited:(NSEvent*)event {
    // 마우스가 빠져나가면 잠시 후 페이딩이 시작된다.
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(startFade:) userInfo:nil repeat:NO];
    [self setFadeTimer:timer];
}

//실제 투명화 동작
-(void)startFade:(NSTimer*)timer {
    [NSAnimationContent beginGroup]; // ???
    [[NSAnimationContext currentContext] setDuration:10.0];
    [[[self window] animator] setAlphaValue:3.0];
    [NSAnimationContext endGrouping];

    [self setFadeTimer:nil]; // 애니메이션이 시작됨과 동시에 타이머는 nil로 초기화한다.
}
@end

[OSX/iOS] 날짜와 시간을 다루기

날짜와 시간을 위한 프로그래밍을 위해서는 기본적으로 NSDate를 사용한다. NSDate는 2001년 1월 1일 자정을 기점으로 현재시간 (혹은 특정 시점)까지의 초단위로 경과한 시간을 저장하고 있는 객체이다. 이렇게 단순히 누적된 초 시간으로는 두 시점의 선/후 관계를 파악하는 등의 단순 비교 작업은 가능하지만, 구체적인 날짜나 요일에 연관된 작업을 하기는 매우 어렵다. 예를 들어 올해 크리스마스가 무슨 요일인지를 구하는 일은 NSDate 객체 만으로는 사실상 매우 힘들다.

코코아가 (혹은 코코아터치가) 날짜/시간을 다루는 방식을 이해하려면 NSCalendar와 NSDateComponent 객체에 대해서도 알아둘 필요가 있다. NSDateComponent는 몇 월, 몇 일 등 날짜라는 정보를 구성하는 달력에서의 단위들에 대한 정보를 기술하는데 사용하며, 실제 NSDate 객체와 NSDateComponent 사이를 NSCalendar 객체가 연결해준다고 생각하면 된다. 즉, 기준일로부터 흐른 시간으로 오늘이 몇 월 몇 일인지를 알려면, “달력”이 있어야 한다. 왜냐하면 달력에 따라 오늘이 몇 년, 몇 월, 몇 일인지가 결정될 수 있기 때문이다.

NSDate

NSDate는 특정한 시점이며, 이는 기준시 (2001년 1월 1일 자정)로부터 경과한 시간의 합이다. 즉, 기준시로부터 지금 이 순간까지 몇 초나 흘렀나하는 것을 세어서 지금이 언제인지를 아는 것이다.  NSDate 객체를 생성하면 기본적으로 생성되는 현재 시점의 정보를 가지게 된다.

NSDate *now = [[NSDate alloc] init];

혹은 생성자 메소드를 사용해 간단히 아래와 같이 쓸 수도 있다.

NSDate *now = [NSDate date];

NSDate 객체를 생성할 때는 이와 더불어 현재 시점을 기준으로 경과한 초를 가지고 특정한 시점의 객체를 생성할 수도 있다. 어제와 내일에 대한 날짜는 다음과 같이 생성한다.

NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *today = [NSDate date];
NSDate *tomorrow, *yesterday;

tomorrow = [[NSDate alloc] initWithTimeIntervalSinceNow:secondsPerDay];
yesterday = [[NSDate alloc] initWithTimeIntervalSinceNow:-secondsPerDay];

혹은 현재 시점인 today를 가지고,

tomorrow = [today dateByAddingTimeInterval:secondsPerDay];
yesterday = [today dateByAddingTimeInterval:-secondsPerDay];

와 같이 생성이 가능하다.

NSDate 는 별도로 특정한 날짜를 기준으로 생성될 수도 있다. 이를 테면 다음과 같이

NSDate *someday = [NSDate dateWithNaturalLanguageString:@"12/25/01"];

이라고 하면 2012년의 크리스마스를 나타내는 NSDate 객체를 생성할 수 있다. 단지 미국에서 사용하는 “월/일/년”의 순서이기 때문에 조금 불편하거나 헷갈릴수는 있겠다.

* 이 메소드는 OSX에서만 동작한다. iOS에서 NSCalendar는 이 메소드를 사용할 수 없다.

NSCalendar

앞서 설명하였지만, NSDate는 특정 시점을 나타내는 절대적인 숫자값이다. 하지만 실제로 이는 기준시로부터 몇 초가 지났는지를 일일이 계산해야 하기 때문에 우리에게 익숙한 날짜/시간 단위와는 무관하다. 우리가 인지하는 날짜나 시간 개념의 단위들은 NSDateComponents에서 제공한다. 하지만 앞서도 간략히 설명했듯이, NSDateComponents는 각 시간 단위들을 표시하기 위한 컨테이너이지, 실제 날짜로 계산되지는 않는다. 즉 무언가 년/월/일/요일 등에 대한 상관관계를 알아내기가 힘들기 때문이다. 하지만 애플의 엔지니어들은 이 힘든 작업을 이미 다 처리해서 NSCalendar로 만들어 두었다.

NSDate로부터 우리가 흔히 인식하는 달력에서의 단위를 추출하기 위해서는 NSCalendar  객체의 도움을 받아야 한다. NSCalendar는 NSDate로부터 NSDateComponent 객체를 생성할 수 있고, 또 그 반대의 역할도 수행할 수 있다.

그런데 달력이 세상에는 한가지 단위만 존재하는 것이 아니다. 흔히 쓰는 양력은 그레고리언력인데, 그 외에도 히브리달력, 이슬람달력, 일본달력(음력인가? 어쨌거나 우리 나라의 음력 날짜는 일본이나 중국과 또 다르다!) 등의 다양한 달력이 있다. 각 달력마다 한 달에 들어있는 날의 수라든지 그런 정보가 다르기 때문에 어떤 달력을 사용하느냐에 따라서 NSDateComponent에서 구하는 값이 달라질 수 있다. 이런 달력의 종류는 상수로 지정되어 있다. 몇 가지 달력을 생성하는 방법은 아래를 참고한다.

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendar *japanese = [[NSCalendar alloc] initWithCalendarIdentifier:NSJapaneseCalendar];
NSCalendar *currentCalendar = [[NSLocale currentLocale] objectForKey:NSLocaleCalendar];
NSCalendar *currentUserCalendar = [NSCalendar currentCalendar];

특히 사용하는 달력은 사용자의 언어나 국가와 관련이 있어서 로케일 정보로부터 현재 달력을 가져올 수 있음을 주목하자.

날짜 요소와 달력

NSDateComponent는 날짜를 이루는 달력상의 요소인 년, 월, 일, 시, 분, 초 등의 정보를 표현하기 위한 객체이다. 아쉽게도 이 객체는 년, 월, 일 등의 값을 표현하기만 할 뿐이지,  스스로 날짜에 대한 비교나 계산을 수행할 수 없다. 예를 들어 2012년 2월 20일을 표현하는 NSDateComponent를 생성한다고 하자.

NSDateComponent *someday = [[NSDateComponent alloc] init];
someday.day = 20;
someday.month = 2;
someday.year = 2004;

특이점이라면 특이점인데, 날짜 요소에서의 월, 일 등의 값은 실제 날짜의 값과 일치한다. 배열에서 인덱스가 0에서 시작하는 것과 달리 날짜 요소는 1에서 시작하게 된다. 어쨌든 이렇게 생성된 날짜 요소는 그저 달력에서 어떤 날짜에 해당하는 표현일 뿐이므로, 이렇게 만들어진 someday에 대해서 weekday 프로퍼티로 요일 값을 받아오려해도 아무 것도 얻을 수 없다. 특정 날짜를 사용해서 해당 요일을 구하는 것은 뒤에서 다시 다뤄보도록 하겠다.

NSDateComponents의 각 속성들은 실제로 서로 연관되어 계산되지 않는다. 즉 “2012년 2월 31일”과 같은 식의 표기로도 날짜 요소 객체를 생성할 수 있다. 날짜 속성으로 지정한 날짜를 실제 날짜로 계산하기 위해서는 이를 바탕으로 한 NSDate 객체를 만들어 내어야 한다.

이 때 NSCalendar의 -components:fromDate: 메소드를 이용하는데, 여기서 컴퍼넌트에 들어가는 인자는 날짜에 요소 단위에 대한 비트마스크 값이다. 오늘 날짜에 대해서 요일과 일자는 다음과 같이 구해야 한다. (요일은 일요일을 시작으로 1=일요일, 2=월요일… 과 같이 진행된다. 단, 현재 달력이 그레고리안력이라는 것을 전제해야 한다!)

NSDate *today = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *weekdayComponent = [calendar components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];

NSInteger day = [weekdayComponent day];
NSInteger weekday = [weekdayComponent weekday];

날짜만을 고려하기

친구의 생일 등을 저장하기 위해서는 년도나 일시는 중요하지 않고 그저 월과 일자만으로 날짜를 생성할 필요가 있다. 일반적으로 NSDate의 메소드들을 통해서는 년도가 없는 날짜 객체를 만들 수 없지만 다음과 같이 사용하는 것은 가능하다.

NSDateComponents *components = [[NSDateComponents alloc] init];
components.month = 11;
components.day = 7;
NSCalendar *calendar  = [NSCalendar currentCalendar];
NSDate *birthday = [calendar dateFromComponents:components];

이 코드는 (아마도) 서기 1년을 기준으로 한 날짜 객체를 생성하는데, 나중에 이 날짜를 사용할 때는 월과 일의 정보만 사용하는 것이 좋다. (그렇지 않으면 천 살이 넘는 친구를 갖게 된다.) 나중에 연도를 빼고 표시하기 위해서는 NSDateFormatter의  +dateFormatFromTemplate: options: locale: 메소드를 활용하면 간단하게 날짜를 포매팅할 수 있다. 포매팅 템플릿에 대한 정보는 다음 링크에서 확인할 수 있다.

유니코드 날짜 포맷 패턴

날짜를 계산하기

금주의 일요일을 구하는 예를 생각해보자. NSDateFormatter는 특정한 시점을 나타내지 않고 달력의 단위를 표현하기만 한다고 했다. 이를 사용하여 몇일 앞, 몇 일 뒤 혹은 몇 달 몇 일 앞뒤의 날짜를 계산할 수 있다. 즉 날짜의 오프셋으로 활용할 수 있다.

NSDate *today = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents = *weekdayComponents = [calendar components:NSWeekdayCalendarUnit fromDate:today];

// 오늘 날짜의 요일을 뽑아 이를 사용해 일요일의 날짜를 구하기
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
offsetComponents.day = 0 - (weekdayComponents - 1);
NSDate *beginningOfThisWeek = [calendar dateByAddingComponents:offsetComponents toDate:today options:0];

weekday = 1 인 날이 일요일이므로 오늘의 weekday에서 1을 뺀값의 음수를 취해 이를 오프셋으로 활용하여 오늘로부터 거꾸로 올라간 날짜를 구하면 된다.

몇 일 남았는지 계산해보기

NSDate의 timeInterval을 서로 빼서 몇 일이 남았는지 계산해보는 것이 가능하다 하겠다. 하지만 이는 초 단위의 차이이므로 보다 사람이 알기 쉽게 몇 개월, 몇 일이 남았는지를 계산하는 것은 다음과 같이 계산할 수 있다. 올 해 크리스마스까지 몇 일이 남았나 계산해보자.

NSDate *today = [NSDate date];
NSDate *christmas = [NSDate dateWithNaturalString:@"12/25/12"];
NSCalendar *cal = [NSCalendar currentCalendar];
NSUInteger units = NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [cal components:units fromDate:today toDate:christmas options:0];
NSInteger months = components.month;
NSInteger days = components.day + 1;

이 때 만약 지금 시각이 오후 8시라한다면 자정까지는 4시간 가량이 남은게 된다. 이는 24시간보다 작으므로, 두 시간 간격은 1일을 채 못미치게 된다. 따라서 이 간극을 해소하기 위해서 날짜에는 1일을 더해주어야 올바른 날짜 사이의 값을 알게 된다. 만약 이 계산을 timeInterval을 사용해서 구해야 한다면 상당히 번거로운 단위 변환 작업을 반복해야 했을 것이다.

시간 차이를 구하는 다른 방법 – 노멀라이징

시간 차이를 구할 때 이미 경과해버린 오늘의 날짜를 무시해야하려면 비교하는 각 시점의 날짜의 자정으로 (반드시 자정이 아니더라도) 시간을 노멀라이징할 필요가 있다. 즉 비교하는 두 날짜의 시간을 같은 시간으로 맞추면 24시간 단위로 딱 떨어지기 때문에 항상 정확하게 두 날짜 사이의 간격을 구하기가 용이해지는 것이다.

이 때 사용하기 좋은 메소드는 -ordinalityOfUnit: inUnit: forDate: 이다. 이 메소드는 inUnit:의 인자의 단위를 기준으로 작은 단위의 경과를 구한다. 다음 예는 NSCalendar에서 두 날짜 사이의 날짜 수 차이를 구해준다. 이 때 경과한 시간은 무시하므로 오늘과 내일을 전달하면 1일 구할 수 있다.

@implementation NSCalendar (MyNormalizedCalculation)
 -(NSInteger)daysWithinEraFromDate:(NSDate *)startDate
                            toDate:(NSDate *)endDate
{
 NSInteger startDay = [self ordinalityOfUnit:NSDayCalendarUnit
                                      inUnit:NSEraCalendarUnit
                                     forDate:startDate];
 NSInteger endDay = [self ordinalityOfUnit:NSDayCalendarUnit
                                    inUnit:NSEraCalendarUnit
                                   forDate:endDate];
 return endDay - startDay;
}

위 메소드는 NSCalendar에 대해 카테고리로 구현되었다. 각각의 날짜를 2001년 1월 1일에서부터 구해 노멀라이징하였다. 즉 NSEraCalendarUnit 단위에서 경과한 NSDayCalendar 단위의 수를 구하는 것이다. 만약 두 번째 파라미터를 NSYearCalendarUnit을 썼다면 그 해의 1월 1일로부터 경과한 일 수를 구하게 되는 것이다.

그런데 이 방법은 초단위의 NSTimeInterval을 사용한다. 만약 초단위의 값을 구해 이 방법을 사용한다면 32비트 시스템에서는 사용할 수 없게된다. (오버플로우되어 작은 값이 나온다)  따라서 아이폰에서는 이 경우에는 보다 조금 더 노가다가 들어간 방식으로 돌려 구현한다. 로직은 앞서 말한 것과 완전히 동일하다.

@implementation NSCalendar (MyNormalizedCalculation)
-(NSInteger)daysFromDate:(NSDate *)startDate
                  toDate:(NSDate *)endDate
{
  NSCalendarUnits units = NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
  NSDateComponents *cp1, *cp2;
  cp1 = [self components:units fromDate:startDate];
  cp2 = [self components:units fromDate:endDate];
  cp1.hour = 12;
  cp2.hour = 12;
  NSDate *date1 = [self dateFromComponents:cp1];
  NSDate *date2 = [self dateFromComponents:cp2];
  return [[self components:NSDayCalendarUnits
                  fromDate:date1
                    toDate:date2
                   options:0] day]; 
}
@end

즉 두 날짜를 NSDateComponents를 통해 수동으로 노멀라이징하여 날짜 간격을 구하도록 할 수도 있다.

정리

날짜를 다루는 일은 사실, 아주 특별한 경우를 제외하고는 그렇게 많지 않다. 대부분은 DB나 코어데이터에서 레코드를 추가하거나, 정렬하거나 수정할 때 현재 날짜를 사용하는 수준에서 완료되기 때문에 날짜에 대해 비교하고 계산하는 작업을 그리 자주하게 되지는 않을 것이다. 하지만 이런 날짜와 같은 부분에 대해서는 국가마다 사용하는 달력이 다를 수도 있고, 엄청나게 많은 것들을 고려해야 (윤달같은 특별한 규칙들) 할 수도 있다. 하지만 이런 작업은 NSCalendar에 의해서 이미 많은 부분이 쉽고 편리하게 이용할 수 있도록 다 만들어져 있다. 그외에도 이 포스트에서 다루지 못한 내용들도 많은데, 자세한 사항은 TIme & Date Programming Guide를 참고하면 되겠다.

20120126 :: Dock의 그리드 아이콘 크기 변경

Dock의 우측 부분에는 응용 프로그램 아이콘이 아닌 폴더를 집어 넣어, 해당 폴더의 내용에 빠르게 접근할 수 있는 스택이 있다. 이 스택은 설정하기에 따라서 부채꼴로 펼쳐지는 스택이 될 수도 있고, 가로/세로 사각형의 형태로 배열되는 그리드가 될 수도 있다. (물론 아이콘 항목이 많은 폴더는 그리드로 설정된다.)

화면의 크기가 비교적 작은 맥북의 경우에는 이 그리드의 아이콘 크기가 좀 작은 편이고, 화면이 큰 아이맥에서는 이 그리드 아이콘이 크게 표시되는데, 트랙패드를 사용하는 경우에는 아이콘이 큰 만큼 마우스 포인터가 화면을 이동해야 하는 경로가 커져서 은근히 피로감을 느끼게 된다.

그리드의 아이콘이 클 때

이 경우에는 ⌘키를 누른채로 +/- 키를 눌러 그리드의 아이콘 크기를 조절할 수 있다.

20120117 :: OSX의 메모리 상태 보는 법

맥은 얼마 쓰지도 않아서 메모리를 다쓴다?

윈도에서 맥으로 넘어와서 버리기 힘든 나쁜 습관 중 하나는 메모리의 상태를 걱정하는 일이다. 무슨 소린고 하니 마치 메모리 먹는 괴물처럼 맥은 시스템에 달린 램을 거의 대부분 써버린다. 시스템의 메모리는 활성상태보기(activity)라는 앱을 실행해서 확인할 수 있는데, 여기서 보면 “여유 메모리”에 진짜 여유가 있는 경우가 좀처럼 없기가 십상이다.

그래서 메모리의 여유 공간을 확보해주는 앱들도 유/무료로 많이 팔리고 있는 중인데, 꼭 이런 앱을 돌릴 필요가 있을까 싶은 생각이 든다. 물론 윈도에서의 메모리 확보 프로그램과는 달리, 이 앱들은 시스템에 해악을 끼친다고는 생각되진 않는다. 아무튼 이러한 일종의 ‘오해’는 맥의 메모리 관리 방법에 대한 무지에서 비롯된다고 생각되는데, 이런 메모리 정보를 어떻게 이해해야 할까?

먼저 활성상태보기 앱을 실행해보면 시스템 메모리가 현재 어떻게 사용되고 있는지를 보여준다. 각각의 내용은 다음과 같다.

  • 여유공간 : 말 그래도 여유공간이다. 시스템 메모리 중 사용되지 않고 있으며, 언제든 사용할 수 있는 공간이다.
  • 와이어드 : Wired 상태의 메모리는 특히 앱의 실행 코드가 올라가 있는 공간이다. 따라서 하드디스크 위의 가상메모리 공간으로 스와핑이 불가능하다.
  • 활성 : 활성 메모리 영역은 앱들이 정보를 올려두고 사용하는 공간이다. 메모리가 부족한 상황이 된다면 시스템은 이 영역의 데이터 중 당장 사용되지 않는 내용들을 가상 메모리로 옮겨주게 된다.
  • 비활성 : 아마 시스템을 사용하다보면 가장 많은 분량을 차지하게 되는 메모리 공간이다. 비활성 메모리는 최근에 종료한 앱이 사용했던 공간이다. 이 부분을 바로 해제해서 여유 공간으로 확보할 수 있지만, 실제로는 일반적인 사용자는 동일한 앱을 빈번히 종료/재시작하므로, 비활성 메모리에 이전 앱이 사용하던 정보를 남겨두면, 그 앱을 재실행할 때 빠르게 구동할 수 있다는 장점이 있다. 물론 메모리가 부족한 상황에서는 이 공간을 free 하여 필요한 메모리를 즉시 확보할 수 있다. 현재 시중에 나도는 메모리 확보용 앱은 이 비활성 메모리 영역을 해제해주는 것외에 하는 내용은 없다.

따라서 시스템에서 사용 가능한 메모리 공간은 “여유공간 + 비활성”의 크기 만큼이 되겠다. 그리고 이 두 영역을 합해도 필요한 메모리보다 부족하다면 시스템은 활성 메모리 중의 일부를 디스크로 옮겨서 필요한 메모리 영역을 확보하게 된다. 이 때 사용하는 가상 메모리의 크기가 VM이며, VM에 대해 얼마나 액세스했는가 하는 정보가 페이지출력/입력에 표시된다.

이 페이지 입력/출력의 양이 많으면 많을수록 더 많은 양의 메모리가 필요해서 그 만큼 페이징을 했다는 이야기이며, 하드디스크는 램에 비해 훨씬 더 속도가 느리므로 시스템의 전체적인 체감 성능이 떨어진 것처럼 느껴질 수 있다. 하지만 대부분의 경우에는 그 정도까지로 메모리를 사용하는 케이스는 좀 드물다.

맥이 메모리를 99%, 100%까지 쓰는 것은 메모리를 잘 못 관리하기 때문이 아니라, 그만큼 메모리를 잘 활용하고 있는 (그것도 극대화하여 사용) 증거이므로 굳이 메모리 관리 앱을 사용하여 여유 공간을 수동을 매번 잡아줄 필요는 없다.

덧 : 이는 몇 번 지적한 내용인데, 윈도용 메모리 확보 프로그램은 맥으로 치면 현재의 활성상태 메모리 영역에 있는 데이터를 디스크의 스왑공간으로 강제로 옮기는 기능을 수행한다. 따라서 일시적으로 여유공간이 증가하는 것처럼 보이지만, 필요이상의 하드디스크 액세스를 발생시키므로 오히려 앱을 사용하는 속도는 느려진다. 윈도에서의 메모리 관리도 시스템이 관리하는 것이 가장 낫다고 생각된다. 단, 윈도는 메모리 여유 공간이 제법 남아 있는 상황에서도 가상메모리로 페이징하는 일이 빈번하여 되려 같은 체감성능을 제공하는데 있어 더 많은 램 크기를 요구하는 경우가 많다.

참고자료 : http://support.apple.com/kb/HT1342?viewlocale=ko_KR&locale=ko_KR

20120112 :: [OSX] 메일 첨부파일 때문에 하드디스크 용량이 걱정될 때

아이클라우드가 약 5GB 가량의 공간을 제공해주고 있고 그래서 iOS 기기의 무선 백업을 사용하지 않는다면 거의 이 만큼의 공간을 메일 용량으로 활용할 수 있는데, Gmail의 경우에도 점점 용량이 늘어나면서 상당히 많은 양의 공간을 제공하고 있다. 경우에 따라서는 Gmail 계정을 여러 개 사용하는 경우도 있을 수 있어서 메일함을 동기화하는 경우에는 적지 않은 디스크 공간이 메일에 의해 점유된다.

HDD를 사용하는 경우에는 별로 문제가 되지 않지만, 맥북에어와 같이 디스크 용량이 그리 넉넉치 못한 환경에서는 이런 메일 사용이 꽤나 부담이 되는데, 하지만 메일앱에 다운로드 받아둔 메일은 Spotlight에서 바로 검색이 가능해서 이 편리함을 뿌리치기가 힘들다.

그런 경우에는 메일 메시지는 하드디스크에 보관해두되, 비교적 용량이 큰 첨부파일들은 저장하지 않도록 하는 방법을 사용하면 메일 검색도 쉽게 할 수 있고, 디스크 용량도 절약할 수 있다.

메일 앱을 실행해서 환경설정 패널을 열어 계정 탭을 본다. 계정을 선택하면 오른쪽에 계정의 설정을 할 수 있는데, 이 곳에 “고급” 탭을 클릭해 본다.

위 그림에서 볼 수 있듯이 “오프라인 상태에서 보기 위해 메시지 복사본 유지”를 선택하는 옵션이 있는데, 기본값이 “모든 메시지와 첨부 파일”이다. 이를 “모든 메시지, 첨부파일은 생략함”으로 바꾸면 메일 메시지는 저장하지만 첨부파일은 메시지를 열어 별도로 다운로드 받도록 하기 때문에 필요한 파일만 그 때 그 때 찾아서 저장하면 된다.