TIL 7: MRC 속 ARC 조심하기

TL;DR

  • MRC 환경에서 ARC로 생성되는 객체를 조심하자.
    특히, 객체 생성용 클래스 메소드를 조심하자.
    (예: [NSArray array])

MRC 환경 내부의 ARC

iOS 개발을 MRC 환경에서 해 본 사람이라면, 곳곳에 ARC가 숨어 있다는 사실을 알 것이다. 그래서 이것을 잘못 알고 사용하면, 잘못된 메모리 참조로 인해 앱 크래시가 발생할 수 있다. 이것이 개발하고 테스트할 때 발견하지 못 하고, 출시한 후 사용자로부터 발견된다면… 급하게 버그를 수정하고 다시 배포하느냐 정신이 없을 것이다. 😱

과거에 한창 Objective-C로 개발할 때는 숙지하고 있었는데 잠시 몇개월간 Swift의 세계에 있었다고, 까먹고 있어서 개발 중에 크래시가 발생하곤 했다. 다행히 기존에 문제가 있었던 메모리 누수 해결을 하면서 발견해서 상처를 잘 봉합했다. 다음에 꼭 메모리 관련해서 글을 한 번 정리해야겠다.

간단히 말해서 통상적으로 MRC 환경 속에서 ARC로 사용하는 객체는 autorelease 메소드를 호출한 경우이다. 보통 ARC로 사용하길 원하는 부분은 직접 autorelease 메소드를 호출하니 문제가 없을 것이다. 그런데, 입문자라면 잘 모를 수 있는 것이 UIKit 등과 같은 공식 프레임워크에 정의되어 있는 객체 생성용 클래스 메소드이다.

init 메소드로 생성하지 않고, [NSArray array] 메소드와 같은 클래스 메소드로 객체를 생성한 경험이 있을 것이다. 이 경우에 해당 메소드로 생성한 객체는 이미 autorelease 메소드를 호출한 객체이므로, 추가적으로 메모리 해제를 하면 안 된다. 다른 말로 release 메소드를 호출하면 안 된다. 이런 용도의 메소드는 클래스 이름을 본 딴 Prefix를 가지므로, 여러 예시를 본다면 패턴에 익숙해질 것이다.

또한, 직접 커스텀 클래스에 객체 생성용 클래스 메소드를 정의한다면, 공식 프레임워크와 같이 ARC 객체로 생성하길 권장한다. 그렇지 않으면, 혼동되어 더 많은 버그와 실수를 남길 것이다. ☠️

TIL 8: HTTP 메시지로 다중 파일 업로드하기 TIL 6: unowned 레퍼런스 피하기