Haru's 개발 블로그

[Objective-C] 메모리 관리 본문

IOS/Objective-C

[Objective-C] 메모리 관리

Haru_29 2023. 3. 11. 00:17

1. 애플리케이션과 메모리

  • 애플리케이션 - 객체의 행위, 속성으로 동작
  • 객체의 생성 - 메모리 공간 차지
  • 사용이 끝나면 객체를 해제

 

2.ARC

  • 옵젝씨에서의 메모리 관리 기법
    • 객체에 '사용 중'이라고 기록 -> 소유(own)하기
    • 리테인 카운트: 객체의 소유된 개수
    • 리테인 카운트 0 -> 사용하지 않는다 -> 해제
  • 수동 시절
    • 소유하기 -> 리테인 카운트 증가
    • 소유권 해제 -> 리테인 카운트 감소
    • 많은 오류와 어려움
  • 자동 시절
    • ARC 기술 제공 (iOS 5)
    • 자동 작성
  • 객체 소유하기 -> 포인터 변수로 할당
    • NSObject *ptr =[[NSObject alloc]init];
  • 객체 소유권 해제 -> 포인터 변수를 nil 혹은 다른 객체
    • ptr = nil;
  • 추가 포인트로 소유하기
NSObject *ptr = [[NSObject alloc]init];
NSObject *ptr2 = ptr;
ptr = nil;

 

객체의 메모리 해제 확인하기

  • 객체가 해제되면서 dealloc 메소드 동작
  • 클래스(Tracer)생성하고 메소드 작성
@implementation Tracer
-(void)dealloc{
    NSLog(@"메모리에서 객체 해제");
}
@end

 

3. 생존주기

3-1. 변수의 스코프

  • 객체
    • 힙(Heap) 영역
    • 소유하는 포인터 변수에 의해서 해제 결정
  • 지역 변수(Local Variable)
    • 선언된 코드 단위가 종료되면 사라진다.
  • 멤버 변수(프로퍼티)
    • 객체가 해제되면 사라진다.
     

3-2. 생존주기 수식자(Lifetime Qualifier)

  • 모든 포인터 변수가 객체를 소유하지 않는다.
  • 생존주기 수식자
    • strong
    • weak
    • unsafe_unretained
    • autoreleasing
  • 객체를 소유하는 포인터: 강한 참조
  • 객체를 소유하는 강한 참조 : strong
  • 프로퍼티
    • @property (strong) NSString *strongProperty;
  • 멤버 변수, 스택 변수 (언더바 2개)
    • NSObject __strong *strongPtr;
  • 생략 가능

 

  • 객체를 소유하지 않는 포인터: 약한 참조
  • 객체를 소유하지 않는 약한 참조: weak, unsafe_unretained
  • 프로퍼티
    • @property (weak) NSString *weakProperty;
  • 멤버 변수, 스택 변수(언더바 2개)
    • NSObject __weak *weakPtr;
  • 소유되지 않는 객체는 해제

 

  • 객체에 강한 참조가 없고 약한 참조만 있으면? -> 바로 해제(NULL이 나옴)
NSObject __weak *weakPtr = [[NSObject alloc]init];
NSLog(@"weak ptr : %@", weakPtr);

 

  • 약한 참조만 있으면 객체 해제
  • 객체가 해제되고 포인터의 주소는??
    • weak: 자동으로 nil 할당, zeroing weak reference
    • unsafe_unretained: 주소 유지
  • 해제된 메모리 공간에 접근 주의
  • autoreleasing: 포인터의 주소로 객체 전달
  • 주로 NSError에서 많이 사용
__autoreleasing NSError *error = nil;
BOOL ret = [str writeToFile:filePath atomically:YES 
encoding:NSUTF8StringEncoding error:&error];

 

4. 콜렉션과 메모리 관리

  • 콜렉션에 객체 저장 -> 객체를 소유
  • 콜렉션에서 객체 삭제 -> 객체의 소유권 해제
  • 배열에 저장, 배열에서 삭제
Tracer *obj =[[Tracer alloc]init];
obj.name = @"Obj";

NSMutableArray *array = [NSMutableArray array];
[array addObject:obj];
//obj포인터의 소유권 해제
obj = nil;
NSLog(@"Obj 포인터의 소유권 해제");
NSLog(@"배열 내 모든 객체 삭제");
[array removeAllObjects];

 

5. 제약 사항

  • 프로퍼티 이름은 new로 시작 못함
  • 강한 순환 참조 주의
  • 리테인 카운트 관련 메소드 사용 금지
    • - (id)retain
    • - (void)release
    • - (id)autorelease
    • (NSUInteger)retainCount
  • 메모리 해제 용도로 dealloc 사용 금지
  • strong으로 상호 참조시 : 해제 안됨 -> 강한 순환 참조 -> 한쪽에 weak 걸어주기!

'IOS > Objective-C' 카테고리의 다른 글

[Objective-C] 셀렉터와 프로퍼티  (0) 2023.03.10
[Objective-C] 객체 생성 메소드  (0) 2023.03.09
[Objective-C] 동적 타입과 바인딩  (0) 2023.03.09
[Objective-C] Class 상속  (0) 2023.03.09
[Objective-C] Class 만들어보기  (0) 2023.02.28
Comments