이 자료는 이영록강사님이 2011년 iOS 개발자 포럼에서 발표한 내용을 약간 개선하고 정리한 자료입니다.
iOS의 메모리관리 기법은 retain count라고 하는 독특하면서도 효율적인 방법을 사용하며 최근에 발표된 Xcode에서는 Automatic Reference Counting(ARC) 기법을 통해 release를 사용하에 객체를 소거하는 불편함을 많이 개선하였습니다.
본 자료에서는 이러한 점에 대한 비교적 상세한 설명을 담고 있습니다.
79. 메모리-Heap 영역
동적할당 변수
• 프로그램 실행중에 Heap 영역으로부터 필요한 만큼 메모리를 할당받는다.
• 사용이 완료되면 시스템에 반납하여야 한다
• C언어에서는 malloc() 함수에 의해 할당
• C++ 언어에서는 new 키워드에 의해 할당
• Objective-C 언어에서는 alloc 메소드에 의해 할당
장점
• 효율적인 메모리 관리가 가능하다
단점
• 메모리 관리를 프로그래머가 책임지고 해야한다
80. 메모리-Stack 영역
지역변수
• 함수나 블럭안에서 정의되는 변수
• 함수가 종료되거나 프로그램이 종료되면 메모리 공간이 해제됨
• 함수가 받는 매개 변수나 함수내에서 사용되는 지역변수가 이 Stack 영역에 저장
( OS의 관리 )
118. NSObject NSNumberClassAClassB
ClassC의 Instance
obj isa
Stack Heap
Code
ClassC
-methodC
super
-methodB
super
-methodA
super
NSNumber *num=[[NSNumber alloc] init];
+alloc
NSNumber의 Instance
-init -init
+alloc
119. NSObject NSNumberClassAClassB
ClassC의 Instance
obj isa
Stack Heap
Code
ClassC
-methodC
super
-methodB
super
-methodA
super
NSNumber *num=[[NSNumber alloc] init];
+alloc
NSNumber의 Instance
num
-init -init
+alloc
120. NSObject NSNumberClassAClassB
ClassC의 Instance
obj isa
Stack Heap
Code
ClassC
-methodC
super
-methodB
super
-methodA
super
NSNumber *num=[[NSNumber alloc] init];
+alloc
NSNumber의 Instance
num
isa
-init -init
+alloc
121. NSObject NSNumberClassAClassB
ClassC의 Instance
obj isa
Stack Heap
Code
ClassC
-methodC
super
-methodB
super
-methodA
super
NSNumber *num=[[NSNumber alloc] init];
+alloc
NSNumber의 Instance
num
isa
super
-init -init
+alloc
289. Accessor Methods
// setter를 사용하게 되면 다음과 같은 validation(유효성) 검사가 가능하다
// 이를 통해 더욱더 안전한 데이터 사용이 가능하다
@implementation ClassA
...
- (void)setScore:(int)val {
if( val 0 )
score = 0;
else
score = val;
}
- (int)score {
return score;
}
@end
295. Property 속성지정
@property (getter=score, setter=setScore:) int score;
- (void)setScore:(int) val {
score = val;
}
- (int)score {
return score;
}
@synthesize score
// 위 문장은 아래 코드를 생성한다. setScore, score 메소드를 생성한다
296. Property 속성지정
@property (readonly, getter=score) int score;
@synthesize score
// 위 문장은 아래 코드를 생성한다
// readonly속성에 의해 setScore메소드는 생성하지 않는다
297. Property 속성지정
@property (readonly, getter=score) int score;
- (int)score {
return score;
}
@synthesize score
// 위 문장은 아래 코드를 생성한다
// readonly속성에 의해 setScore메소드는 생성하지 않는다
298. Property 속성지정
@property (readonly, getter=scoreValue) int score;
@synthesize score
// 위 문장은 아래 코드를 생성한다
// readonly속성에 의해 setScore메소드는 생성하지 않는다
// getter 메소드 scoreValue로 지정되어 있다
299. Property 속성지정
@property (readonly, getter=scoreValue) int score;
- (int)scoreValue {
return score;
}
@synthesize score
// 위 문장은 아래 코드를 생성한다
// readonly속성에 의해 setScore메소드는 생성하지 않는다
// getter 메소드 scoreValue로 지정되어 있다
300. Property 속성지정
@property (readonly) int score;
@synthesize score
// 위 문장은 아래 코드를 생성한다.
// 디폴트 getter 메소드 명은 속성값의 이름인 score이다.
// readonly 속성에 의해 setScore메소드는 생성하지 않는다.
301. Property 속성지정
@property (readonly) int score;
- (int)score {
return score;
}
@synthesize score
// 위 문장은 아래 코드를 생성한다.
// 디폴트 getter 메소드 명은 속성값의 이름인 score이다.
// readonly 속성에 의해 setScore메소드는 생성하지 않는다.
307. Property 속성지정
@property (nonatomic, retain) UIButton *scoreButton;
// nonatomic한 속성을 가진 scoreButton 메소드 생성
// atomic한 객체는 안정성을 보장해야 하므로 임의의 스레드가
// scoreButton 값을 사용하는 중에는 다른 스레드가 이 값에 대한 setter를
// 호출하지 못하도록 한다.
308. Property 속성지정
@property (nonatomic, retain) UIButton *scoreButton;
// nonatomic한 속성을 가진 scoreButton 메소드 생성
// atomic한 객체는 안정성을 보장해야 하므로 임의의 스레드가
// scoreButton 값을 사용하는 중에는 다른 스레드가 이 값에 대한 setter를
// 호출하지 못하도록 한다.
- (void)setScoreButton:(UIButton *)newButton {
if ( scoreButton != newButton ) {
[scoreButton release];
scoreButton = [newButton retain];
}
}
-(UIButton *)scoreButton
{
return scoreButton;
}
309. nonatomic vs atomic
쓰레드
- 어떠한 프로그램의 프로세스내에서 실행되는 흐름의 단위를 말함
- 한 프로그램 내에는 여러개의 쓰레드가 동작할 수 있음
- 하나의 값을 여러 쓰레드가 동시에 접근하여 변경하게 되면 문제가 발생
310. nonatomic vs atomic
atomic
- setter/getter는 다른 쓰레드 setter 메소드를 행하는 중에는
접근할 수 없도록 한다.(read-write safety)
- atomic한 접근을 보장하기 위해서는 수행 속도면에서 손해를 보게된다
nonatomic
- nonatomic 속성은 atomic한 기능을 보장하지 않는다
- 대신 수행속도가 빠르다
쓰레드 안정성(thread safety)
- atomic은 쓰레드 안정성을 보장해 주지는 않는다
- 즉 setter나 getter가 작동하는 중에 release가 이루어지게 되면
crash가 발생하는데 이러한 부분까지는 atomic한 속성으로 보장해 주지
않는다
316. Automatic Reference Counting
ARC
- 컴파일러 수준의 기능으로 객체의 참조 횟수를 추적하는 일을 프로그래머가 하지
않고 컴파일러가 대신 수행하는 형태로 메모리 관리기능을 보강한 것이다.
- Objective-C 언어자체의 기능은 아님
- 2011년 Mac OS X Lion과 iOS 5 운영체제에서 도입되었다
- Xcode 4.2부터 사용가능하다
317. ARC 규칙
ARC 사용시의 규칙은 다음과 같다
- retain, release, retainCount, autorelease, dealloc을 프로그
래머가 직접 호출할 수 없다
- id 형이나 void * 형을 직접 형변화시킬 수 없다
- NSAutoreleasePool 객체를 사용할 수 없다
- NSAllocateObject 와 NSDeallocateObject 함수를 호출할 수 없다
- C 구조체내의 객체 포인트를 사용할 수 없다
- 메모리 존(NSZone)을 사용할 수 없다
318. ARC 컴파일 옵션설정
ARC 사용시 컴파일 옵션 설정
- Project 시작시 Use Automatic Reference Counting을 체크
323. 객체간의 참조
ARC 기능-객체간의 참조 카운터를 자동으로 관리
객체간의 참조
- 1:1 참조 또는 1:n 참조가 가능
strong 참조
- 한 객체가 다른 객체를 strong 참조로 참조하고
있는 경우, 참조되고 있는 객체가 소멸되지 않는다.
weak 참조
- 한 객체가 다른 객체를 weak 참조로 참조하고
있는 경우, 참조되고 있는 객체의 생존은 보장되지 않는다