iOS는 아이폰의 OS로 사용되면서 상대적으로 작은 메모리를 가진 아이폰에서 메모리 최적화를 하기 위한 방식이 필요했다.
그 중에서 iOS는 Reference Count를 통한 메모리 관리 체계를 사용하게 되었고, 이를 실현하기 위해서 개발자들은 참조 객체끼리의 레퍼런스 카운트를 직접 관리해주어야 했다.
이런 방식을 MRC(Manual Reference Counting)이라고 불렀다.
MRC
Swift 이전에 iOS 개발은 거의 Objective-C 언어를 통해 개발이 되고 있었다.
MRC 매커니즘에서는 참조 타입의 객체가 alloc을 통해 생성되면, 초기화된 인스턴스는 그 인스턴스를 생성한 또 다른 객체에서 이미 참조가 되고 있기 때문에 RC가 1인 상태로 시작된다.
특정 인스턴스에 대해 지속적으로 참조하기를 원하면 retain 메시지를 통해 RC를 하나 증가시킬 수 있다.
반대로 release 메시지를 보내면 RC를 감소시킬 수 있으며, RC가 0이 되면 더 이상 참조되지 않는 것으로 판단되어 dealloc이 호출되고 인스턴스는 메모리에서 해제된다.
따라서 메모리에서 해제되는 시점에 실행시킬 내용이 있다면 dealloc에 대한 오버라이드로 구현할 수 있다.
-(void)dealloc {
// 메모리 해제 시점에 실행할 로직
[super dealloc];
}
Auto Release
많은 인스턴스들은 짧은 시간에만 참조된 이후 더 이상 필요 없어진다.
이런 인스턴스를 매번 메모리에서 언제 해제할 지 고려하는 것은 매우 번거로운 작업이기 때문에 autorelease라는 기능이 추가되었다.
NSAutoreleasePool 인스턴스를 생성한 후 잠깐 참조하게 될 객체에 autorelease라는 메시지를 보내서 자동 해제 풀에 등록을 할 수 있다.
이렇게 등록된 인스턴스들은 NSAutoreleasePool 인스턴스가 해제되는 시점에 자동으로 모두 해제가 된다.
현재는 직접 인스턴스를 생성하고 등록할 필요 없이 @autoreleasepool 매크로를 통해서 해당 블럭이 끝나는 시점에 자동으로 해제되도록 설정할 수 있다.
반대로 현재는 직접 NSAutoreleasePool 객체를 생성하는 방법은 막혔다.
// 레거시 방식
id pool = [[NSAutoreleasePool alloc] init];
/*
일련의 작업 수행
임시로 생성되는 객체에 autorelease 메시지 전송
*/
[pool release];
// 현재는 이처럼 NSAutoreleasePool 인스턴스를 직접 생성할 수 없다.
// 아래의 구문으로 간단하게 구현할 수 있다.
@autoreleasepool {
/*
일련의 작업 수행
*/
}
다음 포스트에서는 MRC 이후로 사용된 메모리 방식인 ARC와 GC에 대해 다뤄보겠다.
개인적인 공부를 위해 작성한 내용이므로 틀린 내용이나 수정이 필요한 부분이 있을 수 있으니 감안하고 봐주시면 감사하겠습니다.
'iOS' 카테고리의 다른 글
[iOS] MVC, MVP, MVVM 패턴 (1) | 2024.01.22 |
---|---|
[iOS] ARC와 GC의 등장 (1) | 2024.01.09 |