Programming/Mac & iOS

[iOS] Initialization과 Literal

MB Kyle KWON 2016. 5. 16. 21:46

    오늘은 초기화 메소드에 대한 포스팅이다. Objective-C로 개발을 하다보면 가장 많이 구현하는 부분이 초기화 메소드일 것이다. 일반적으로 아래와 같이 초기화 메소드를 사용하게 된다.


-(instancetype)init

{

        self = [super init];

        if (self) {

            //impelment here

        }


        return self;

}


    이중에서 우리가 얘기할 부분은 위에 하이라이팅된 부분이다. 굳이 메모리에 할당되어 있는 self 객체를 슈퍼클래스에서 초기화한 객체로 다시 assign하는 것일까? 주변 다른 개발자 분으로부터 그 해답을 얻었다.


    우선 해답은 super class의 초기화 과정을 거치면서 할당된 메모리의 주소가 변경될 수 있기 때문이다. 메모리 주소가 초기화 과정에서 변경되는 이유는 필자가 Swift의 let (literal)을 통해 이미 공부했던 'String Intern Pool'과 관련되어 있었다.


    객체 지향 언어에서 객체를 할당할 때, 내부적으로는 상수로 관리한다. 상수를 할당하고 각 객체는 그 메모리 주소를 가르키고 있는 것이다. 이렇게 관리하는 이유는 실제로 2개 이상의 객체가 같은 값의 value를 소유하고 있을 때, 개수만큼 메모리를 할당하고 객체를 생성하는 것이 아니라 Pool 안의 같은 상수를 바라보게 함으로써 메모리의 낭비를 줄이기 위함이다. 이해를 돕기 위해 Swift에서 Literal을 공부할 때 사용했던 슬아이드 이미지 를 아래 첨부 하겠다.





    위의 그림처럼 실제로 NSString 객체는 4개이지만 value의 종류가 2개이기 때문에 메모리에 각각 4개의 NSString이 할당되는 것이 아니라 2개의 NSString만 할당되어 메모리를 절약할 수 있는 것이다. 그리고 이를 이용한 이점이 하나 더 있다.


    아래의 이미지를 보면 알 수 있다. NSString이나 NSNumber와 같이 value의 일치를 확인하는 logic을 수행할 때, NSString의 경우 각 문자에 접근하여 비교를 할 경우 아래 2번째 이미지처럼 O(n)의 시간 복잡도를 수행하게 된다. 하지만 Pool과 상수를 이용할 경우 주소값만 비교하면 되기 때문에 비교 연산 시, O(1)의 시간 복잡도로 단순화 된다. 이번에도 이해를 돕기 위해 Swift에서 Literal을 공부 할 때 사용한 슬라이드 이미지를 첨부하겠다.