Objective-C 객체의 생성과 파괴

객체의 생성은 최상위 클래스가 제공하는 alloc메소드에 의해 이루어 지며, 초기화는 init메서드가 담당한다. 일반적으로 alloc으로 재정의 될 필요가 없으나, 초기화를 담당하는 init는 필요에 따라 재정의 될 필요가 있다. 단 개체를 생성하기 위해서 alloc과 init를 모두 사용해야 하는것은 아니다. alloc이 할당된 공간을 0으로 채워주기 때문에 이 공간에 속해있는 멤버변수들의 값을 다른 값으로 바꾸어야 하는 경우가 아니라면 init가 반드시 필요한것은 아니다. 하지만 alloc과 init를 모두 사용하는것이 관례라 할 수 있겠다. 초기화를 init가 아닌 다른 메서드를 이용하여 할수도 있다. 이런 경우에는 alloc와 그 다른 메서드를 호출해야 하겠지. 객체가 더 이상 필요하지 않으면, GNU Object-C의 Object의 경우, free메서드를 사용해서 없애 버릴 수 있다.

/* test.m */
#include <objc/Object.h>
 
@interface Test: Object
{
        int a;
        int b;
}
- (id) init;
- (id) initWith: (int)x with: (int)y;
- (void) print;
@end
 
@implementation Test
- init
{
        [super init];
        a = 0;
        b = 0;
        return self;
}
- (id) initWith: (int)x with: (int)y
{
        [super init];
        a = x;
        b = y;
        return self;
}
- (void) print
{
        printf ("a=%d, b=%d\n", a, b);
}
@end
 
int main ()
{
        Test* x, * y, * z;
 
        z = [Test alloc];
        y = [[Test alloc] init];
        x = [[Test alloc] initWith: 50 with: 60];
 
        [z print];
        [y print];
        [x print];
 
        [x free];
        [y free];
        [z free];
 
        return 0;
}

이 프로그램을 실행하면 다음과 같다.

[bacon@abiyo test]$ gcc -o test test.m -lobjc
[bacon@abiyo test]$ ./test
a=0, b=0
a=10, b=20
a=50, b=60
[bacon@abiyo test]

객체의 생성과는 달리 파괴의 경우는 좀 더 복잡한 양상을 보이는 경우가 많다. 예를 들어, Mac OS X의 NSObject는 Reference Counting을 할수 있는 메서드를 지원하는데, 이런 기능을 사용하려면 이와는 다른 접근방법을 사용해야 한다. 많이 다르지는 않더라도 말이다.

C++의 관점에서 보자면, alloc은 new연산자가 하는 역할을, init는 constructor의 역할을 수행하고 있다고 할수 있다. 다음점이 있다면 C++에서 new를 사용하여 객체를 생성할경우 constructor가 자동으로 호출되지만, Objective-C에서는 alloc과 init를 모두 직접 호출해 주어야 한다는 것이다. 그렇다면 free는 C++의 delete연산자 정도 된다고 보면 되겠다. 여기서도 다른점을 찾는다면 C++에는 destructor라는게 있어서 파괴시에 호출이 되지만 Objective-C에는 그런게 없다는것이다. C++의 destructor같은게 필요하다면 단순히 free를 재정의 하면 되겠다.

 

- (void)free
{
        /* 객체를 파괴할때 뭔가 같이 없애고 싶은게 있으면 여기서 하면 된다.
         * 되도록 super에 free메시지를 보내기 전에 해라. */

        [super free];
}
Comments