Objective-C에서는 클래스의 인스턴스를 생성할 때 메모리를 할당하고 초기화를 해야한다. 아래에 보면 예처럼 메모리 할당과 초기화를 한 줄로 처리하는 것이 보통이다.
메모리를 할당하는데 NSObject 클래스의 alloc과 allocWithZone 메소드가 사용되면, 인스턴스 변수들은 모두 0으로 초기화된다.
모든 클래스는 이름이 init으로 시작하는 초기화 메소드를 제공해야 한다(직접 정의하거나 다른 클래스를 상속하여 init 메소드를 제공해야 한다). 이때 특별한 인자가 필요하지 않으면 init이라는 이름을 그대로 사용하여, 인자가 필요하면 init 뒤에 적절한 이름을 붙여 사용한다. 예를 들면, 파운데이션 프레임워크의 NSView 클래스는 initWithFream: 메소드를, NSString 클래스는 initWithFormat: 메소드를 가지고 있다. NSObject 클래스도 init 메소드를 제공하는데 이것은 단순히 자기 자신, 즉 self를 돌려주는 역활을 한다.
실제로 프로그램을 작성할 때 파운데이션 프레임워크 내의 수많은 클래스를 가져다 쓰게 되는데, 클래스마다 초기화 메소드의 이름이 다른 경우가 많으므로 관련 문서에서 그 이름 및 사용 방법을 정확히 숙지한 후 사용하는 것이 좋다. 메모리 할당과 초기화를 동시에 수행하는 메소드도 많다.
1. 초기화 메소드 구현하기
초기화 메소드를 구현하는 방법 및 제약 사항은 다음과 같다.
메모리를 할당하는데 NSObject 클래스의 alloc과 allocWithZone 메소드가 사용되면, 인스턴스 변수들은 모두 0으로 초기화된다.
모든 클래스는 이름이 init으로 시작하는 초기화 메소드를 제공해야 한다(직접 정의하거나 다른 클래스를 상속하여 init 메소드를 제공해야 한다). 이때 특별한 인자가 필요하지 않으면 init이라는 이름을 그대로 사용하여, 인자가 필요하면 init 뒤에 적절한 이름을 붙여 사용한다. 예를 들면, 파운데이션 프레임워크의 NSView 클래스는 initWithFream: 메소드를, NSString 클래스는 initWithFormat: 메소드를 가지고 있다. NSObject 클래스도 init 메소드를 제공하는데 이것은 단순히 자기 자신, 즉 self를 돌려주는 역활을 한다.
실제로 프로그램을 작성할 때 파운데이션 프레임워크 내의 수많은 클래스를 가져다 쓰게 되는데, 클래스마다 초기화 메소드의 이름이 다른 경우가 많으므로 관련 문서에서 그 이름 및 사용 방법을 정확히 숙지한 후 사용하는 것이 좋다. 메모리 할당과 초기화를 동시에 수행하는 메소드도 많다.
1. 초기화 메소드 구현하기
초기화 메소드를 구현하는 방법 및 제약 사항은 다음과 같다.
- 이름은 init으로 시작한다.
예) initWithFormat:, initWithObjects:, initWithFream:
- 리턴 타입으로 id를 사용한다.
이것은 해당 클래스를 상속한 자식 클래스도 초기화 메소드를 사용하기 때문이다. 클래스에 따라 리턴 타입이 달라져야 하므로 모든 타입을 다룰 수 있는 id 타입을 사용해야 한다.
- 반드시 부모 클래스의 초기화 메소드를 직접 또는 간접으로 호출해야 한다.
클래스의 초기화 메소드는 그 부모 클래스의 초기화 메소드를 호출하고, 다시 부모 클래스의 부모 클래스의 초기화 메소드를 호출하고, 이런 식으로 결국에는 루트 클래스인 NSObject의 초기화 메소드까지 모두 호출되게 된다.
- 부모 클래스의 초기화 메소드가 반환하는 값을 self에 할당한다.
클래스 인스턴스 변수는 크게 '상속을 통해 생성된 인스턴스 변수'와 '현재 클래스에서 생성한 인스턴스 변수'로 나뉜다. '상속을 통해 생성된 인스턴스 변수'는 이 과정을 통해 초기화된다.
예) self = [super initWithFream:fream];
- 인스턴스 변수에 값을 설정할 때 해당 변수에 값을 설정하는 메소드를 호출하는 것보다는 직접 값을 넣는 것이 좋다. 메소드가 실행되는 도중에 예상치 못한 오류가 발생할 수도 있기 때문이다.
- 초기화 메소드를 종료할 때 반드시 self를 반환한다.
다음은 초기화 메소드를 구현한 예이다. 우선 부모 클래스의 초기화 메소드를 호출하고 반환값을 self에 할당한다. 그리고 인스턴스 변수를 별도의 메소드를 사용하지 않고 직접 값을 대입하여 초기화한다. 마지막으로 초기화된 self를 반환한다.
이 예의 클래스는 NSObject를 상속하고 있기 때문에 init 메소드를 호출하고 있는데, 다른 경우에는 부모 클래스의 초기화 메소드 이름을 알아내서 호출해야 할 수도 있다.
initWithWidth:height: 메소드에서 부모 클래스의 초기화 메소드가 돌려주는 반환값을 검사하는 것은 해당 메소드가 실패하여 nil을 반환하는 경우를 처리하기 위해서다. 일반적으로 조건문을 사용하여 그 반환값이 유효한 경우에만 다음 작업을 수행하도록 한다.
2. 메모리 할당과 초기화의 결합
파운데이션 프레임워크와 많은 클래스는 메모리 할당과 초기화를 동시에 수행하는 메소드를 제공한다. 즉, 메모리 할당 메소드와 초기화 메소드를 별도로 호출하지 않고 하나의 메소드로 처리하는 것이다. 이러한 클래스 메소드들은 일반적으로 다음과 같이 클래스 이름으로 시작되는 이름을 가진다.
이 메소드들의 반환 타입이 id인 이유는 초기화 메소드가 반환 타입으로 id를 사용하는 것과 같다.
출처 - 도전! 아이폰4 프로그래밍
'프로그래밍 > Object-C' 카테고리의 다른 글
객체 제거하기(메모리 해제) (0) | 2011.09.04 |
---|---|
객체 사용하기(메모리 관리) (0) | 2011.09.04 |
AppDelegate 전역변수 사용 (0) | 2011.09.03 |
userInteractionEnabled (0) | 2011.09.03 |
UITouch (0) | 2011.09.01 |