iOS 메모리관리

Post on 18-Jan-2015

2.610 views 3 download

description

이 자료는 이영록강사님이 2011년 iOS 개발자 포럼에서 발표한 내용을 약간 개선하고 정리한 자료입니다. iOS의 메모리관리 기법은 retain count라고 하는 독특하면서도 효율적인 방법을 사용하며 최근에 발표된 Xcode에서는 Automatic Reference Counting(ARC) 기법을 통해 release를 사용하에 객체를 소거하는 불편함을 많이 개선하였습니다. 본 자료에서는 이러한 점에 대한 비교적 상세한 설명을 담고 있습니다.

Transcript of iOS 메모리관리

iOS Memory Management

이영록

실행시 메모리 구조

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

실행시 메모리 구조

Stack

Heap

Data

Code(Text) 프로그램코드가����������� ������������������  저장

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

프로그램코드가����������� ������������������  저장

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

동적할당을����������� ������������������  위한����������� ������������������  공간

프로그램코드가����������� ������������������  저장

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

동적할당을����������� ������������������  위한����������� ������������������  공간

지역변수와����������� ������������������  매개변수가����������� ������������������  저장

프로그램코드가����������� ������������������  저장

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

동적할당을����������� ������������������  위한����������� ������������������  공간

지역변수와����������� ������������������  매개변수가����������� ������������������  저장

프로그램코드가����������� ������������������  저장}메모리����������� ������������������  사용량����������� ������������������  변동없음프로그램����������� ������������������  종료시����������� ������������������  해제

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

동적할당을����������� ������������������  위한����������� ������������������  공간

지역변수와����������� ������������������  매개변수가����������� ������������������  저장

프로그램코드가����������� ������������������  저장}메모리����������� ������������������  사용량����������� ������������������  변동없음프로그램����������� ������������������  종료시����������� ������������������  해제

-객체가����������� ������������������  생성되는����������� ������������������  공간사용량이����������� ������������������  변동메모리관리의����������� ������������������  대상영역

실행시 메모리 구조

Stack

Heap

Data

Code(Text)

전역변수와����������� ������������������  정적변수가����������� ������������������  저장

동적할당을����������� ������������������  위한����������� ������������������  공간

지역변수와����������� ������������������  매개변수가����������� ������������������  저장

프로그램코드가����������� ������������������  저장}메모리����������� ������������������  사용량����������� ������������������  변동없음프로그램����������� ������������������  종료시����������� ������������������  해제

-객체가����������� ������������������  생성되는����������� ������������������  공간사용량이����������� ������������������  변동메모리관리의����������� ������������������  대상영역

사용량이����������� ������������������  계속해서����������� ������������������  변경OS가����������� ������������������  관리-

메모리-Code 영역

프로그램의����������� ������������������  명령문들-����������� ������������������  이����������� ������������������  명령문에����������� ������������������  의해����������� ������������������  프로그램은����������� ������������������  작동한다

메모리-Data 영역

전역변수• 프로그램 전역에서 사용가능한변수

정적변수• 실행중에 항상 일정한 메모리 공간에 유지됨• 블럭을 벗어나도 자동으로 제거되지 않음

메모리-Heap 영역

동적할당 변수• 프로그램 실행중에 Heap 영역으로부터 필요한 만큼 메모리를 할당받는다.• 사용이 완료되면 시스템에 반납하여야 한다• C언어에서는 malloc() 함수에 의해 할당• C++ 언어에서는 new 키워드에 의해 할당• Objective-C 언어에서는 alloc 메소드에 의해 할당장점• 효율적인 메모리 관리가 가능하다단점• 메모리 관리를 프로그래머가 책임지고 해야한다

메모리-Stack 영역

지역변수• 함수나 블럭안에서 정의되는 변수• 함수가 종료되거나 프로그램이 종료되면 메모리 공간이 해제됨• 함수가 받는 매개 변수나 함수내에서 사용되는 지역변수가 이 Stack 영역에 저장( OS의 관리 )

@interface ClassA : NSObject {}+ (void) imClassMethod- (void) methodA;@end

@implementation ClassA+ (void) imClassMethod { NSLog(@"I’m Class Method");}- (void) methodA { NSLog(@"I’m A");}@end

@interface ClassB : ClassA {

}- (void) methodB;@end

@implementation ClassB- (void) methodB { NSLog(@"I’m B");}@end

@interface ClassC : ClassB {

}- (void) methodC;@end

@implementation ClassC- (void) methodC { NSLog(@"I’m C");}@end

int main (int argc, const char * argv[]) { ClassC *obj = [[ClassC alloc] init];

[obj methodC]; [obj methodB]; [obj methodA]; [obj methodX];NSNumber *num =[[NSNumber alloc] init];

return 0;

}

Stack Heap

Code

ClassC *obj = [[ClassC alloc] init];Stack Heap

Code

ClassC *obj = [[ClassC alloc] init];Stack Heap

Code

ClassC

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

Stack Heap

Code

ClassC

+alloc

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

Stack Heap

Code

ClassC

-init+alloc

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

obj

Stack Heap

Code

ClassC

-init+alloc

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

obj

Stack Heap

Code

ClassC

-init+alloc

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-init+alloc

ClassC *obj = [[ClassC alloc] init];

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-init+alloc

ClassC의 Instance

obj isa

Stack Heap

Code

[obj methodC];

ClassC

-init+alloc

ClassC의 Instance

obj isa

Stack Heap

Code

[obj methodC];

ClassC

-methodC-init+alloc

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

[obj methodB];

-init+alloc

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

[obj methodB];

super

-init+alloc

ClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

[obj methodB];

super

-init+alloc

ClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

[obj methodB];

super-methodB

-init+alloc

ClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodB

[obj methodA];

-init+alloc

ClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodB

[obj methodA];

super

-init+alloc

ClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodB

[obj methodA];

super

-init+alloc

ClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodB

[obj methodA];

super

-methodA-init+alloc

ClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

-init+alloc

ClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-methodX-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

[obj methodX];

super

-init+alloc

NSObjectClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

-init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

-init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

+alloc-init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

+alloc

NSNumber의 Instance

-init -init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

+alloc

NSNumber의 Instancenum

-init -init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

+alloc

NSNumber의 Instancenum

isa

-init -init+alloc

NSObject NSNumberClassAClassB

ClassC의 Instance

obj isa

Stack Heap

Code

ClassC

-methodC

super-methodBsuper

-methodA

super

NSNumber *num=[[NSNumber alloc] init];

+alloc

NSNumber의 Instancenum

isa

super

-init -init+alloc

메모리 관리란?

메모리 관리란?

메모리 관리란?Heap

메모리 관리란?Heap

object

메모리 관리란?Heap

object

object

메모리 관리란?Heap

object

object

object

메모리 관리란?Heap

object

object

objectobject

메모리 관리란?Heap

object

object

objectobject

object

메모리 관리란?Heap

object

object

objectobject

object

object

메모리 관리란?Heap

object

object

objectobject

object

objectobject

메모리 관리란?Heap

object

object

objectobject

object

objectobject

object

메모리 관리란?Heap

object

object

objectobject

object

objectobject

object

object

메모리 관리란?Heap

object

object

objectobject

object

objectobject

object

object object

메모리 관리란?Heap

object

object

objectobject

object

objectobject

object

object

메모리 관리란?Heap

object

object

objectobject

object

objectobject

object

메모리 관리란?Heap

object

object

objectobject

object

object

object

메모리 관리란?Heap

object

object

objectobject

object

object

메모리 관리란?Heap

object

object

objectobject

object

메모리 관리 방식명시적해제 가비지콜렉터 레퍼런스����������� ������������������  카운팅

방식프로그래머가����������� ������������������  객체를����������� ������������������  생성해서����������� ������������������  사용하다����������� ������������������  필요가����������� ������������������  없을때����������� ������������������  명시적으로����������� ������������������  해제

가비지����������� ������������������  콜렉터가����������� ������������������  수시로����������� ������������������  실행되어서����������� ������������������  필요없는����������� ������������������  객체

들을����������� ������������������  해제

레퍼런스(리테인)카운트에����������� ������������������  의해����������� ������������������  객체를����������� ������������������  해제

특징전적으로����������� ������������������  프로그래머에����������� ������������������  

의해����������� ������������������  관리시스템부하없슴����������� ������������������  

프로그래머가����������� ������������������  관리안함시스템부하

프로그래머가����������� ������������������  오너쉽정책에����������� ������������������  의거해서����������� ������������������  관리시스템부하없슴

언어C++Delphi

JavaC#

Objective-C

Reference Count Systemint main (int argc, const char * argv[]) { NSNumber *num = [[NSNumber alloc] init];NSNumber *num1 = [num retain];NSNumber *num2 = num;[num release];[num1 release];

return 0;}

Reference Count SystemHeapstack

Heapstack

NSNumber *num = [[NSNumber alloc] init];

Heapstack

NSNumber의객체

NSNumber *num = [[NSNumber alloc] init];

Heapstack

numNSNumber의객체

NSNumber *num = [[NSNumber alloc] init];

Heapstack

numNSNumber의객체

NSNumber *num = [[NSNumber alloc] init];

Heapstack

numNSNumber의객체

= 1

NSNumber *num = [[NSNumber alloc] init];

retainCount

Heapstack

NSNumber *num1 = [num retain];

numNSNumber의객체

= 1retainCount

Heapstack

NSNumber *num1 = [num retain];

numNSNumber의객체

= 1

num1

retainCount

Heapstack

NSNumber *num1 = [num retain];

numNSNumber의객체

= 1

num1

retainCount

Heapstack

NSNumber *num1 = [num retain];

numNSNumber의객체

num1

+ 1retainCount

Heapstack

NSNumber *num1 = [num retain];

numNSNumber의객체

num1

= 2retainCount

Heapstack

numNSNumber의객체

num1

= 2retainCount

NSNumber *num2 = num;

Heapstack

numNSNumber의객체

num1

= 2retainCount

NSNumber *num2 = num;

num2

Heapstack

numNSNumber의객체

num1

= 2

[num release];

retainCount

num2

Heapstack

numNSNumber의객체

num1

- 1

[num release];

retainCount

num2

Heapstack

numNSNumber의객체

num1

= 1

[num release];

retainCount

num2

Heapstack

numNSNumber의객체

num1

= 1

[num1 release];

retainCount

num2

Heapstack

numNSNumber의객체

num1

- 1

[num1 release];

retainCount

num2

Heapstack

numNSNumber의객체

num1

[num1 release];

= 0retainCount

num2

Heapstack

numNSNumber의객체

num1

[num1 release];

= 0

dealloc

retainCount

num2

Heapstack

numNSNumber의객체

num1

[num1 release];

= 0retainCount

num2

Heapstack

num

num1

[num1 release];

num2

Reference Count System- (id)init

- (id)retain

- (oneway void)release

- (id)autorelease

- (id)copy...

Reference Count System- (id)init

- (id)retain

- (oneway void)release

Reference Count System- (id)init

- (id)retain

- (oneway void)release

{ . . .

retrainCount=1; .

}

Reference Count System- (id)init

- (id)retain

- (oneway void)release

{ . . .

retrainCount=1; .

}

{ retrainCount+=1; return self;}

Reference Count System- (id)init

- (id)retain

- (oneway void)release

{ . . .

retrainCount=1; .

}

{ retrainCount+=1; return self;}

{ retrainCount-=1; if (retrainCount==0) [self dealloc];}

잘못된 메모리 관리int main (int argc, const char * argv[]) { NSNumber *var1 = [[NSNumber alloc] init];NSNumber *var2 = [[NSNumber alloc] init];NSNumber *var3 = [[NSNumber alloc] init];NSNumber *var4 = [[NSNumber alloc] init];

var2 = [[NSNumber alloc] init];[var3 release]; [var3 isEqualToNumber: var1];

return 0;}

잘못된����������� ������������������  메모리관리

잘못된����������� ������������������  메모리관리Heapstack

Heapstack

NSNumber *var1 = [[NSNumber alloc] init];

Heapstack

object1var1

NSNumber *var1 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

NSNumber *var2 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

NSNumber *var3 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

object4

var4

NSNumber *var4 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

object4

var4

var2 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

object4

var4

object5

var2 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

object4

var4

object5

var2 = [[NSNumber alloc] init];

Heapstack

object1var1

object2var2

object3var3

object4

var4

object5

var2 = [[NSNumber alloc] init];

memoryleak

Heapstack

object1var1

object2var2

object3var3

object4

var4

object5

[var3 release];

memoryleak

Heapstack

object1var1

object2var2

var3

object4

var4

object5

[var3 release];

memoryleak

Heapstack

object1var1

object2var2

var3

object4

var4

object5

[var3 isEqualToNumber: var1];

memoryleak

Heapstack

object1var1

object2var2

var3

object4

var4

object5

[var3 isEqualToNumber: var1];

memoryleak

danglingpointer

Ownership Policy

alloc����������� ������������������  을����������� ������������������  사용한����������� ������������������  인스턴스����������� ������������������  생성

copy를����������� ������������������  사용한����������� ������������������  인스턴스����������� ������������������  복사

retain을����������� ������������������  사용한����������� ������������������  보존

자기����������� ������������������  몫의����������� ������������������  retainCount����������� ������������������  ‘1’을����������� ������������������  가지는����������� ������������������  것

인스턴스����������� ������������������  객체의����������� ������������������  오너만이����������� ������������������  그����������� ������������������  인스턴스의����������� ������������������  해제에����������� ������������������  대해서����������� ������������������  책임을����������� ������������������  진다.

-����������� ������������������  오너가����������� ������������������  되는����������� ������������������  방법

Ownership PolicyNSString * str = [[NSString alloc] init];NSString * str1 = str;....[str1 release];[str setString:@"나는 주인이다"]; // X

Ownership PolicyNSString * str = [[NSString alloc] init];NSString * str1 = str;....[str1 release];[str setString:@"나는 주인이다"]; // X

NSString * str = [[NSString alloc] init];NSString * str1 = [str retain];....

[str setString:@"나는 주인이다"]; // O[str release];

Ownership PolicyNSString * str = [[NSString alloc] init];NSString * str1 = [str retain];....[str1 release];[str setString:@"나는 주인이다"];[str release];

Ownership Policy

NSString * str = [[NSString alloc] init];NSString * str1 = str;....[str setString:@"나는 주인이다"];[str release];

NSString * str = [[NSString alloc] init];NSString * str1 = [str retain];....[str1 release];[str setString:@"나는 주인이다"];[str release];

Autorelease Pools

Autorelease Pools

Autorelease PoolsNSAutoreleasePool * pool =

[[NSAutoreleasePool alloc] init];NSString *var1 = [[NSString alloc] init];NSString *var2 = [[NSString alloc] init];NSString *var3 = [[NSString alloc] init];[var1 autorelease]; [var2 autorelease];[var3 autorelease];[pool release];

Autorelease PoolsHeapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

object2

object3

pool

Autorelease PoolsHeapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

object2

object3

pool

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

object2

object3

pool

[var1 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

[var1 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

[var1 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

[var2 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

[var2 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

[var2 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

[var3 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

[var3 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

[var3 autorelease];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

[pool release];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

release

[pool release];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

release

release

[pool release];

Heapstack

object1var1

var2

var3

NSAutoreleasePool의 객체

autorelease

object2

object3

pool

autorelease

autorelease

release

release

release

[pool release];

NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];

[var1 autorelease];

NSAutoreleasePool * pool2 = [[NSAutoreleasePool alloc] init];[var2 autorelease];

NSAutoreleasePool * pool3 = [[NSAutoreleasePool alloc] init];[var3 autorelease];[pool3 release];[pool2 release];[pool1 release];

Autorelease Pools 중첩사용

NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];

[var1 autorelease];

NSAutoreleasePool * pool2 = [[NSAutoreleasePool alloc] init];[var2 autorelease];

NSAutoreleasePool * pool3 = [[NSAutoreleasePool alloc] init];[var3 autorelease];[pool3 release];[pool2 release];[pool1 release];

Autorelease Pools 중첩사용

NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];

[var1 autorelease];

NSAutoreleasePool * pool2 = [[NSAutoreleasePool alloc] init];[var2 autorelease];

NSAutoreleasePool * pool3 = [[NSAutoreleasePool alloc] init];[var3 autorelease];[pool3 release];[pool2 release];[pool1 release];

Autorelease Pools 중첩사용

NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];

[var1 autorelease];

NSAutoreleasePool * pool2 = [[NSAutoreleasePool alloc] init];[var2 autorelease];

NSAutoreleasePool * pool3 = [[NSAutoreleasePool alloc] init];[var3 autorelease];[pool3 release];[pool2 release];[pool1 release];

Autorelease Pools 중첩사용

Convenience Constructor객체명으로 시작되는 생성자[NSString string.......][NSArray array.........][NSNumber number.......][NSData data...........] . .

편리한 생성자들은 autorelease 객체를 반환 하므로 계속 사용하려면 retain 메세지를 보내 소유권을 획득해야한다.

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

BlueBird *newBird = [[[self class] alloc] init];

newBird.flyAnimate = [flyAnimate copy];

newBird.sitAnimate = [sitAnimate copy];

newBird.tailAnimate =[tailAnimate copy];

newBird.flyExploAnimate = [flyExploAnimate copy];

newBird.sitExploAnimate = [sitExploAnimate copy];

return newBird;

}

Object CopyNSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

Object Copy

Heapstack

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

Object Copy

Heapstack

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

Object Copy

Heapstack

str object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

Object Copy

Heapstack

str object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount =1

Object Copy

Heapstack

str

str1

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount =2

Object Copy

Heapstack

str

str1

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount object2

=2

Object Copy

Heapstack

str

str1

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount object2

str2

=2

Object Copy

Heapstack

str

str1

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount object2

str2

=2

Object Copy

Heapstack

str

str1

object1

NSString *str = [[NSString alloc] init];NSString *str1 = [str retain];NSString *str2 = [str copy];

retainCount object2

str2

=2

retainCount =1

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

ShallowCopy

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

var3

object3

NSString *str

ShallowCopy

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

var3

object3

NSString *str

ShallowCopy

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

var3

object3 obj2

NSString *str

ShallowCopy

Deep VS Shallow CopiesHeapstack

var1 object1 obj1

NSString *str

var2

object2

NSString *str

var3

object3 obj2

NSString *str

ShallowCopy

DeepCopy

Accessor Methods@interface ClassA : NSObject { int score;}- (void)setScore:(int)val; //setter- (int)score; //getter@end

@implementation ClassA- (void)setScore:(int)val { score = val;}- (int)score { return score;}@end

Accessor Methods

@implementation ClassA- (void)setScore:(int)val { score = val;}- (int)score { return score;}@end

@interface ClassA : NSObject { int score;}@property int score;//- (void)setScore:(int) val; //setter//- (int)score; //getter@end

Accessor Methods@interface ClassA : NSObject { int score;}@property int score;//- (void)setScore:(int) val; //setter//- (int)score; //getter@end

@implementation ClassA@synthesize score=score;//- (void)setScore:(int) val {//score = val;//}//- (int)score {//return score;//}@end

Accessor Methods@interface ClassA : NSObject { int score;}@property int score;//- (void)setScore:(int) val; //setter//- (int)score; //getter@end

@implementation ClassA@synthesize score;//- (void)setScore:(int) val {//score = val;//}//- (int)score {//return score;//}@end

Accessor Methods// setter를 사용하게 되면 다음과 같은 validation(유효성) 검사가 가능하다// 이를 통해 더욱더 안전한 데이터 사용이 가능하다

@implementation ClassA...- (void)setScore:(int)val {

if( val < 0 ) score = 0;

else score = val;

}- (int)score { return score;}@end

Accessor Methods

Accessor Methodsint main (int argc, const char * argv[]) {

ClassA *classA = [[ClassA alloc] init]; [classA setScore:999]; NSLog(@"Num:%i", [classA score]); classA.score = 777;// [classA setScore:777]; 호출 NSLog(@"Num:%i", classA.score);

return 0;}

Property 속성지정분류 옵션 설명

메소드지정getter=methodA getter를 명시적으로 지정

메소드지정setter=methodB setter를 명시적으로 지정

읽기쓰기속성readonly 읽기전용, getter만 생성

읽기쓰기속성readwrite(*) 읽기쓰기

스레드 처리atomic(*) 멀티쓰레드시 메쏘드 Lock

스레드 처리nonatomic Non-atomic

할당방식

assign(*) 주소만 할당

할당방식 retain 객체를 retain해서 할당할당방식

copy 객체를 복사해서 할당

Property 속성지정@property (getter=score, setter=setScore:) int score;

@property (readonly, getter=score) int score;

@property (readonly, nonatomic) int score;

@property (nonatomic, retain) NSNumber score;

@property (nonatomic, copy) NSNumber score;

@property (nonatomic, assign) NSNumber score;

Property 속성지정@property (getter=score, setter=setScore:) int score;

@synthesize score

// 위 문장은 아래 코드를 생성한다. setScore, score 메소드를 생성한다

Property 속성지정@property (getter=score, setter=setScore:) int score;

- (void)setScore:(int) val { score = val;}

- (int)score { return score;}

@synthesize score

// 위 문장은 아래 코드를 생성한다. setScore, score 메소드를 생성한다

Property 속성지정

@property (readonly, getter=score) int score;

@synthesize score

// 위 문장은 아래 코드를 생성한다// readonly속성에 의해 setScore메소드는 생성하지 않는다

Property 속성지정

@property (readonly, getter=score) int score;

- (int)score { return score;}

@synthesize score

// 위 문장은 아래 코드를 생성한다// readonly속성에 의해 setScore메소드는 생성하지 않는다

Property 속성지정

@property (readonly, getter=scoreValue) int score;

@synthesize score

// 위 문장은 아래 코드를 생성한다// readonly속성에 의해 setScore메소드는 생성하지 않는다// getter 메소드 scoreValue로 지정되어 있다

Property 속성지정

@property (readonly, getter=scoreValue) int score;

- (int)scoreValue { return score;}

@synthesize score

// 위 문장은 아래 코드를 생성한다// readonly속성에 의해 setScore메소드는 생성하지 않는다// getter 메소드 scoreValue로 지정되어 있다

Property 속성지정@property (readonly) int score;

@synthesize score

// 위 문장은 아래 코드를 생성한다.// 디폴트 getter 메소드 명은 속성값의 이름인 score이다.// readonly 속성에 의해 setScore메소드는 생성하지 않는다.

Property 속성지정@property (readonly) int score;

- (int)score { return score;}

@synthesize score

// 위 문장은 아래 코드를 생성한다.// 디폴트 getter 메소드 명은 속성값의 이름인 score이다.// readonly 속성에 의해 setScore메소드는 생성하지 않는다.

Property 속성지정@property (getter=score, setter=setScore:) int score;

@property (readonly, getter=score) int score;

@property (readonly, nonatomic) int score;

@property (nonatomic, retain) NSNumber *score;

@property (nonatomic, copy) NSNumber *score;

@property (nonatomic, assign) NSNumber *score;

Accessor Methods@property (retain) NSString *str;

@property (copy) NSString *str;

@property (assign) NSString *str;

Accessor Methods@property (retain) NSString *str;

@property (copy) NSString *str;

@property (assign) NSString *str;

- (void)setStr:(NSString *)newStr { if (str != newStr) { [str release]; str = [newStr retain]; }}

Accessor Methods@property (retain) NSString *str;

@property (copy) NSString *str;

@property (assign) NSString *str;

- (void)setStr:(NSString *)newStr { if (str != newStr) { [str release]; str = [newStr retain]; }}

- (void)setStr:(NSString *)newStr { if (str != newStr) { [str release]; str = [newStr copy]; }}

Accessor Methods@property (retain) NSString *str;

@property (copy) NSString *str;

@property (assign) NSString *str;

- (void)setStr:(NSString *)newStr { if (str != newStr) { [str release]; str = [newStr retain]; }}

- (void)setStr:(NSString *)newStr { if (str != newStr) { [str release]; str = [newStr copy]; }}

- (void)setStr:(NSString *)newStr { str = newStr;}

Property 속성지정

@property (nonatomic, retain) UIButton *scoreButton;// nonatomic한 속성을 가진 scoreButton 메소드 생성// atomic한 객체는 안정성을 보장해야 하므로 임의의 스레드가// scoreButton 값을 사용하는 중에는 다른 스레드가 이 값에 대한 setter를// 호출하지 못하도록 한다.

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;}

nonatomic vs atomic

쓰레드- 어떠한 프로그램의 프로세스내에서 실행되는 흐름의 단위를 말함- 한 프로그램 내에는 여러개의 쓰레드가 동작할 수 있음- 하나의 값을 여러 쓰레드가 동시에 접근하여 변경하게 되면 문제가 발생

nonatomic vs atomicatomic- setter/getter는 다른 쓰레드 setter 메소드를 행하는 중에는접근할 수 없도록 한다.(read-write safety)- atomic한 접근을 보장하기 위해서는 수행 속도면에서 손해를 보게된다

nonatomic- nonatomic 속성은 atomic한 기능을 보장하지 않는다- 대신 수행속도가 빠르다

쓰레드 안정성(thread safety)- atomic은 쓰레드 안정성을 보장해 주지는 않는다- 즉 setter나 getter가 작동하는 중에 release가 이루어지게 되면crash가 발생하는데 이러한 부분까지는 atomic한 속성으로 보장해 주지않는다

Case which OftenCause Confusion

Using Collections

NSMutableArray *array = <#Get a mutable array#>;

NSUInteger i; // ... for (i = 0; i < 10; i++) { NSNumber *convenienceNumber =

[NSNumber numberWithInteger:i]; [array addObject:convenienceNumber]; }

Using Collections

NSMutableArray *array = <#Get a mutable array#>;

NSUInteger i; // ... for (i = 0; i < 10; i++) { NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger:i]; [array addObject:allocedNumber]; [allocedNumber release];

}

Returning Object from Method

Wrong Case- (NSString *)fullName { NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName] release]; return string;}

- (NSString *)fullName { NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName]; return string;}

Returning Object from Method

Correct Case- (NSString *)fullName { NSString *string = [NSString stringWithFormat:@"%@ %@", firstName, lastName]; return string;}

- (NSString *)fullName { NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,lastName] autorelease]; return string;}

Automatic Reference Counting

ARC- 컴파일러 수준의 기능으로 객체의 참조 횟수를 추적하는 일을 프로그래머가 하지않고 컴파일러가 대신 수행하는 형태로 메모리 관리기능을 보강한 것이다.- Objective-C 언어자체의 기능은 아님- 2011년 Mac OS X Lion과 iOS 5 운영체제에서 도입되었다- Xcode 4.2부터 사용가능하다

ARC 규칙

ARC 사용시의 규칙은 다음과 같다- retain, release, retainCount, autorelease, dealloc을 프로그래머가 직접 호출할 수 없다- id 형이나 void * 형을 직접 형변화시킬 수 없다- NSAutoreleasePool 객체를 사용할 수 없다- NSAllocateObject 와 NSDeallocateObject 함수를 호출할 수 없다- C 구조체내의 객체 포인트를 사용할 수 없다- 메모리 존(NSZone)을 사용할 수 없다

ARC 컴파일 옵션설정

ARC 사용시 컴파일 옵션 설정- Project 시작시 Use Automatic Reference Counting을 체크

ARC 자동 변환기능ARC를 사용하지 않는 코드를 자동 변환하는 기능

ARC 컴파일 플래그

Target - Build Setting에서 - Objective-C Automatic Reference Counting을 YES로 설정

ARC 컴파일 플래그

Build Phase - Compile Sources에서 - -fobjc-arc 컴파일러 플래그 설정으로 arc 기능을 적용시킴- -fno-objc-arc 로 arc 기능을 적용시키지 않음

프로퍼티 관련 지시어

ARC 사용전@property (nonatomic, retain) NSString *fname;@property (nonatomic, assign) NSString *lname;@property (nonatomic, assign) NSInteger age;

ARC 사용후// retain 카운터를 유지시키는 대신 strong 참조로@property (nonatomic, strong) NSString *fname;// assign 속성은 weak 참조 속성으로 바뀐다@property (nonatomic, weak) NSString *lname;// arc 적용의 대상이 아님(참조 카운터를 유지하지 않음)@property (nonatomic, assign) NSInteger age;

객체간의 참조

ARC 기능-객체간의 참조 카운터를 자동으로 관리객체간의 참조- 1:1 참조 또는 1:n 참조가 가능strong 참조- 한 객체가 다른 객체를 strong 참조로 참조하고 있는 경우, 참조되고 있는 객체가 소멸되지 않는다.weak 참조- 한 객체가 다른 객체를 weak 참조로 참조하고 있는 경우, 참조되고 있는 객체의 생존은 보장되지 않는다

Retain Cycle

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

Document *ref_doc = [[Document alloc] init];

Page *ref_page = [[NSString alloc] init];

ref_doc.page = [ref_page retain];ref_page.document = [ref_doc retain];

[ref_doc release];// 상호참조로 인해 객체를 소멸시킬 수 없다

Retain Cycle

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

Weak Reference

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

Weak Reference

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

Document *ref_doc = [[Document alloc] init];

Page *ref_page = [[NSString alloc] init];

ref_doc.page = [ref_page retain];ref_page.document = ref_doc;

[ref_doc release];

Weak Reference(약한 참조)

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

Weak Reference(약한 참조)

��)��$ �.�"�(

�$ (%#� (�)*�)�%$(� ),% %� ��)( #�. ��+� �.�"���" '���'�$��( )��) �(� ���� %� ��) �%$)��$( �$ �$()�$�� +�'���"�)��) '���'( )% )�� %)��' %� ��)� �%' �-�#&"�� �%$(���' � )�-) &'%�'�# ,�)� )�� %� ��) '�"�)�%$(��&( (�%,$ �$���*'� ���&�������� ��� �%�*#�$) %� ��) �'��)�( � ���� %� ��) �%' ���� &��� �$ )�� �%�*#�$)� ��� ����%� ��) ��( �$ �$()�$�� +�'���"� )��) !��&( )'��! %� ,���� �%�*#�$) �) �( �$� �� )�� �%�*#�$) %� ��) '�)��$��)�� ���� %� ��) �$� )�� ���� %� ��) '�)��$�� )�� �%�*#�$) %� ��)� $��)��' %� ��) ,%*"� �+�' �� '�"��(������ �%�*#�$)1( '���'�$�� �%*$) ��$$%) ���%#� � *$)�" )�� ���� %� ��) �( '�"��(��� �$� )�� ���� %� ��),%$1) �� '�"��(�� *$)�" )�� �%�*#�$) %� ��) �( ���""%��)���

����� � $ �""*()'�)�%$ %� '�)��$ �.�"�(

textparent

parentparagraph

Paragraph

Page

page

Document

retaindon’tretain

don’tretain

retain

��� (%"*)�%$ )% )�� &'%�"�# %� '�)��$ �.�"�( �( )��) )�� /&�'�$)0 %� ��) (�%*"� '�)��$ �)( /���"�'�$�0 �*) )��))�� ���"�'�$ (�%*"� $%) '�)��$ )���' &�'�$)(� �%� �$ ���*'� ���&������� )�� �%�*#�$) %� ��) '�)��$( �)( &���%� ��)( �*) )�� &��� %� ��) �%�( $%) '�)��$ )�� �%�*#�$) %� ��)� ��� ���"�1( '���'�$�� )% �)( &�'�$) �( �$�-�#&"� %� � ,��! '���'�$��� ,���� �( ��(�'���� #%'� �*"". �$ /���! ����'�$��( )% �� ��)(0��&��������

���! ����'�$��( )% �� ��)(

��)��$�$� �$ %� ��) �'��)�( � /()'%$�0 '���'�$�� )% )��) %� ��)� $ %� ��) ��$$%) �� ���""%��)�� *$)�" �"" %��)( ()'%$� '���'�$��( �'� '�"��(��� $ %� ��)1( "���)�#� �( )��'��. ��)�'#�$�� �. )�� %,$�'( %� �)( ()'%$�'���'�$��(� �$ (%#� ��(�(� )��( ����+�%' #�. $%) �� ��(�'��� �%* #�. ,�$) )% ��+� � '���'�$�� )% �$ %� ��),�)�%*) &'�+�$)�$� )�� %� ��) �'%# ���""%��)�$� �)(�"�� �%' )��(� ��(�(� .%* ��$ %�)��$ � /,��!0 '���'�$��� ,��! '���'�$�� �( �'��)�� �. ()%'�$� � &%�$)�' )% �$ %� ��) ,�)�%*) '�)��$�$� )�� %� ��)�

��)��$ �.�"�( ��������������� ��������������������������������������� �

�� ��) �,$�'(��& �$� ��(&%(�"

strong 참조의 경우 객체들이 상호참조를 할 경우순환고리로 인해 이들을 소멸시킬 수 없다이 때문에 memory 누수가 발생한다weak 참조의 경우 strong 참조와는 달리 참조되고있는 객체의 생존을 보장하지는 않는다

Strong Reference(강한 참조)

A

B

C

D

E

Strong Reference(강한 참조)

- A가 B를 참조하지 않게 되면

A

B

C

D

E

Strong Reference(강한 참조)

A

B

C

D

E

Strong Reference(강한 참조)

- B가 소멸되어야 하지만 B를 E가 참조하고 있고, E는 D가, D는 C가, C는 B가 참조하고 있어서 B,C,D,E는 소멸되지 않고 참조되지도 않는 메모리 누수(leak) 객체가 됨

A

B

C

D

E

Weak Reference(약한 참조)

A

B

C

D

E

Weak Reference(약한 참조)

- E가 B를 참조하되 약한 참조를 할 경우

A

B

C

D

E

Weak Reference(약한 참조)

A

B

C

D

E

Weak Reference(약한 참조)

- A가 B를 참조하지 않게 되면

A

B

C

D

E

Weak Reference(약한 참조)

A

B

C

D

E

Weak Reference(약한 참조)

- B를 참조하는 E가 약한 참조이므로- B는 생존을 보장받지 못한다. - 이 때문에 B는 소멸가능한 객체가 되고

A

B

C

D

E

Weak Reference(약한 참조)

A

C

D

E

Weak Reference(약한 참조)

- B가 소멸되면 C는 참조하는 객체가 없으므로 소멸된다

A

C

D

E

Weak Reference(약한 참조)

A

D

E

Weak Reference(약한 참조)

- C가 소멸되면 D는 참조하는 객체가 없으므로 소멸된다

A

D

E

Weak Reference(약한 참조)

A

E

Weak Reference(약한 참조)

- D가 소멸되면 E는 참조하는 객체가 없으므로 소멸된다

A

E

Weak Reference(약한 참조)

A

Weak Reference(약한 참조)

- 상호참조 객체들이 있더라도 메모리 누수가 발생하지 않는다

A

Thank YOU!