ios 메모리관리
DESCRIPTION
이 자료는 이영록강사님이 2011년 iOS 개발자 포럼에서 발표한 내용을 약간 개선하고 정리한 자료입니다. iOS의 메모리관리 기법은 retain count라고 하는 독특하면서도 효율적인 방법을 사용하며 최근에 발표된 Xcode에서는 Automatic Reference Counting(ARC) 기법을 통해 release를 사용하에 객체를 소거하는 불편함을 많이 개선하였습니다. 본 자료에서는 이러한 점에 대한 비교적 상세한 설명을 담고 있습니다.TRANSCRIPT
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!
Related links
http://Cocos2dDev.com/
http://ivis.cwnu.ac.kr/tc/dongupak/
https://www.facebook.com/groups/smartphone.forum/