[Objective-C] 객체 인스턴스 초기화 메소드

Java는 언어 자체적으로 객체를 생성하거나, 직렬화하거나, 복사하는 등의 방법을 정해 개발자가 따르게 한다. 반면에 Objective-C에서는 아주 기본적인 부분만 정해져 있으며, 나머지는 개발자가 원하는 대로 결정할 수 있다.

즉, 자바에서는 자바 언어가 제공하는 방법이 아닌 다른 방법으로 객체를 생성할 수 없지만, Objective-C에서는 얼마든지 다양한 방법으로 인스턴스를 생성할 수 있다.

객체 인스턴스를 생성하려면 두 단계를 거쳐야 한다. 먼저 메모리를 할당해야 하며, 그 다음으로 초기화한다.

Objective-C에서 초기화 메소드를 작성하려면 다음 규칙을 따라야 한다.

  1. 초기화 메소드는 반드시 슈퍼클래스의 초기화 메소드를 호출해야 한다.
  2. 반드시 self 변수에 적절한 값을 설정해야 한다.
  3. 반드시 nil 인스턴스인지 확인해야 한다.
  4. 반드시 자기 스스로에 대한 포인터를 반환해야 한다.

-(id)init{

self = [super init];
if(self){

     // custom init code

}
return self;
}

(1),(2) 번 지침은 self = [super init] 구문으로 만족시킬 수 있다. Java에서도 언어 자체적으로 슈퍼클래스의 생성자 메소드를 먼저 호출하게 보장하고 있는데, Objective-C에서는 개발자가 알아서 슈퍼클래스의 초기화 메소드를 호출해야 한다.

초기화 메소드에서는 전통적으로 id  자료형을 반환하게 되어 있다. 만약 특정 클래스 타입으로 반환한다면 서브클래스에서 self = [super init]  구문에서 매번 형변환을 해야 하는 불편함이 생긴다.

Objective-C 클래스는 어떤 문제라도 발생하면 객체를 생성하지 못하고 nil 을 반환할 수 있다. – 예)메모리 부족의 경우 nil 반환. 따라서 (3)번 지침처럼 항상 nil 인지를 확인하는 방어 코드가 필요하다. 

인자가 있는 초기화 메소드 예시


@interface TestClass : NSObject {

int num;

}

-(id)initWithNumber:(int)number;

@end

@implementation TestClass

-(id)initWithNumber:(int)number{

self = [super init];
if(self != nil){
   num = number;
}

return self;

}

@end

Objective-C 클래스 가운데 일부는 서브 클래스의 초기화 메소드에서 슈퍼클래스의 특정 초기화 메소드를 사용해야 한다고 지정한 경우(지정 초기화 메소드, designated initializer)가 있다.따라서 클래스를 상속받을 때 개발 문서를 확인할 필요가 있다.

Factory Method라고도 부르는 간편 생성자 메소드는 클래스 메소드로 구현하는 경우가 많다. 간편 생성자 메소드는 동일한 클래스에 대한 인스턴스를 생성해 기본적인 설정을 모두 갖춰 반환하는 기능을 제공한다.

NSDictionary 클래스에서 제공하는 간편 생성자 메소드는 다음과 같다.

@interface NSDictionary

+(id) dictionary;
+(id) dictionaryWithObject:(id)object forKey:(id)key;
+(id) dictionaryWithDictionary:(NSDictionary *)dict;
+(id) dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;

@end

간편 생성자 메소드의 이름 명명 규칙을 유심히 볼 필요가 있다. 보통 Objective-C 클래스의 간편 생성자 메소드는 반환타입을 앞에 두고 인자를 With와 함께 사용하는 경우가 많다.

이러한 명명 규칙을 따르는 간편 생성자 메소드는 autorelease 객체를 반환하므로 개발 코드에서 별도로 release 해서는 안된다. 개발자가 클래스에 간편 생성자 메소드를 만든다면 이와 같은 룰을 따르는 것이 통일성 측면에서 좋다.

초기화 메소드를 이용하여 객체 인스턴스 생성하는 코드는 다음과 같다. (클래스 메소드를 이용한 간편 생성자의 경우는 일반적인 클래스 메소드 호출 방법을 사용하면 된다.)

[[TestClass alloc] init];

+(id)alloc 메소드는 NSObject 의 메소드로 새 인스턴스에 필요한 메모리를 할당한다. alloc이 끝난 시점에는 요청한 클래스의 객체 인스턴스가 존재하는 상태이긴 하지만, 아직 초기화된 상태는 아니다. init 과 같은 초기화 메소드를 호출하고, 초기화 메소드가 정상적으로 반환되면 이제 해당 인스턴스를 사용할 준비가 끝난 셈이다.

참고로 [TestClass new] 는 [[TestClass alloc] init] 의 단축명령으로 NSObject 의 +(id)new 메소드는 내부적으로 +(id)alloc 및 -(id)init 메소드를 호출한다. 따라서 인자가 없는 초기화 메소드 경우에만 사용가능하다.

* Reference : Learn Objective-C for Java Developers

Advertisements
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: