본문으로 바로가기

Object-c에서 메모리 관리

category IT를보다/Apple 2011. 9. 23. 17:28
Object-c 런타임에는 java의  gc 가 없다. reference counter 기법으로 반 자동으로 메모리 관리를 한다.

retain +1 증가
release -1 감소
객체 생성시 autorelease  면 자동  관리 하게된다.  autorelease 로 생성되는 객체들은 NSAutoReleasePool 에 등록되게 되고 여기서  reference count들이 자동 관리 되게된다.
autorelease 는 이 Pool에 '등록' 한다는 의미이고 실제  release 처리는 이벤트 루프로 돌아갈때 실제 release 가 일어난다.

함수로 돌려주는 객체는 반드시 오토릴리즈 된 객체로 돌려준다.
1.NSArray *array=[NSArray array];
2.NSArray *array=[NSArray alloc] init] autorelease];
1,2 구문은 완전히 같은 의미의 구문이다.
즉 alloc이 아닌 특별히 제공하는 클래스 함수들은 전부 오토릴리즈 된 객체를 생성한다.
str=[str uppercaseString];  구문이 그러한 예중 하나이다.

NSMutableArray 같은 데이터 관리 객체는 객체를 받으면 해제 또한 책입 지기 때문에 따로 release,retain 을 날려지 않아도 된다. 
즉 자기가 받은 객체는 자신이 책임 지는 원칙을 지키는 구조이다.

함수 내부에서 만들어 쓰고 끝나는 것들은 전부 오토릴리즈로 사용하겠지만 전역변수는 더이상 안쓸때까지 retainCount를 하나 올려둬야 한다. 또 그 객체가 해제될때 호출되는  dealloc 함수에서 해당 전역 변수의 객체들을 다 해제 시켜준다. 

//--- 해더 파일
@interface TEST:UIView{
    NSString *title;
}
@end

//-- 구현 파일
1.title=[[NSString alloc] initWithStirng:@"test"];

2.title=[[class getTitle] retain];

1,2번과 같이  retain 을 하고
dealloc 함수에서 다음과 같이  release 를 해준다. 

-(void)dealloc{
 [super dealloc];
 [title release];
}

Object-c 에서 setter,getter가 Property 라는 속성으로 정의 되는데 이때 메모리 관리를 살펴 보자.
//--- 해더 파일
@interface TEST:UIView{
    NSString *title;
}
@property (nonatomic,retain) NSString *title;
@end

//--구현 파일 
@implementation TEST
@synthesize title;

라고하면 컴파일러가 자동으로   setter 함수와 getter 함수를 만들어 준다.
-(NSString *)title
-(void)setTitle:(NSString) 

getter 는 해당 값을 return 해주니 똑같고 setter 는 속성 키워드에 따라 조금 다르게 작동한다.
1.retain
-(void)setTitle:(NSString *)newTitle{
  [title release];
  title=[newTitle retain];
}

2.assign 
-(void)setTitle:(NSString*)newTitle{
 title=newTitle;
}
위 구문 처럼  assign 경우는 리테인 카운트에 아무런 영향없이 객체의 주소만 지정하게 된다.

프로퍼티가 retain,copy 경우
dealloc  에서 올바른 처리 구문은 

-(void)dealloc{
   [title release];
   title=nil;
   또는 
   self.title=nil;
}
과 같다.
object.title 은  getter 로서 [object title] 이고 object.title=@"d" 는 setter로서 [object setTitle@"d"] 와 같다.
전역 변수는 지정할때 리테인카운트를 하나올리고 안쓸때는 해제를한다. 또한 객체를 사용하다 release를 하면 미련없이 nil처리를 하자.

맥부기에서 문씨님의 메모리 강좌 라는 좋은 글을보고  정리 차원에서 다시 축약해서 정리를 해보았다.  이제 확실히 BAD_ACCESS 같은 에러가 안날 자신이 있습니까?

사실 저는 강좌를 보고 다시를 짜놓은 코드를 봐도 헷갈리다는.. 쿨럭~