Objective-C의 기초 개념을 익히시려는 분들 반갑습니다. : )
Game Designer Snowrimp입니다.

Game Designer라 실망하시는 분들도 계시겠지만, 아래에 시작되는 튜토리얼은 Scott Stevenson이 작성한 튜토리얼을 번역해 둔것이니 안심하셔도 됩니다.

열심히 번역 공부도 할겸 시작한 일이라 매끄럽지 못하게 번역한 부분이나, 다소 의미의 차이가 있는 부분이 있을 수 있습니다. 이점은 저도 안타깝지만 조금씩 고쳐나갈 예정이며, 개선할 부분을 발견하신다면 과감히 덧글 부탁 드립니다. _ _)

이 포스팅으로 인해 아이폰의 메인 언어인 Objective-C의 초석을 다지는 일에 조금이나마 도움이 되셨으면 좋겠습니다.

또한 이 포스팅이 도움이 되셨다면, 원본 아티클에 기부하시는 한국인의 센스 부탁 드립니다.
Suggested amounts: Useful: $5 | Very Useful: $12 | Priceless: $21

 



Objective-C

Objective-C 는 맥 소프트웨어를 만들때 사용하는 주요 언어 입니다. 여러분이 기본적인 객체 개념과 C언어에 어려움이 없다면 Objective-C 의 감을 쉽게 잡을 수 있을 것입니다. 만약 C를 모른다면 먼저 C Tutorial 튜토리얼을 읽어 보십시오.

번역자노트. 위에서 링크된 C Tutorial의 번역본이 여기 있습니다. : )

이 튜토리얼의 작성과 일러스트는 Scott Stevenson 에 의해 쓰여졌습니다.
 
Copyright © 2008 Scott Stevenson


Calling Methods

가능한 빨리 시작해 보겟습니다, 아래의 간단한 예제들을 보시죠. object(이하 객체)에서 메소드를 호출하는 기본적인 문법 입니다:
 
[object method]; [object methodWithInput:input];
메소드는 값을 반환할 수 있습니다:
 
output = [object methodWithOutput]; output = [object methodWithInputAndOutput:input];
여러분들은 클래스들에서 메소드를 호출할 수 있습니다. 아래의 예제에서 있듯이, 우리는 NSString 객체를 반환하는 NSString 클래스의 string 메소드들를 호출할 수 있습니다:
 
id myObject = [NSString string];
Id 타입은 myObject 변수가 어떤 종류의 오브젝트든 참조할 수 있는것을 의미하므로, 여러분들의 어플리케이션을 컴파일할 때 실제 클래스와 매소드들을 모르는 경우 사용합니다.

이 예제에서, 오브젝트 타입이 NSString이 될 것이므로 우리는 타입을 바꿀 수 있습니다:
 
NSString* myString = [NSString string];
지금 이것은 NSString 변수이므로, 컴파일러는 NSString을 지원하지 않는 이 오브젝트의 메소드를 사용하고자 하면 우리에게 경고를 할 것입니다.

객체 타입의 오른쪽에 별표(*)가 있음을 주목하십시오. 모든 Objective-C  객체 변수들은 포인터 타입입니다. id 타입은 포인터 타입으로 미리 정의되어있으므로, 별표를 필요로하지 않습니다.
 

Nested Messages

많은 언어에서 내제되어 있는 메소드 또는 함수를 호출하는 방법은 이렇습니다:
 
function1 ( function2() );
function2의 결과는 function1의 인풋으로 전달됩니다. Objective-C 에서는 내제된 메시지를 이렇게 표현합니다:
 
[NSString stringWithFormat:[prefs format]];
읽기 어렵게 되기 쉽기 때문에, 한줄에 두개 이상의 내제된 메시지를 호출은 피하십시오.
 

Multi-Input Methods

어떤 메소드들은 입력변수를 여러개 가지고 있습니다. Objective-C 에서는, 메소드 이름을 몇가지 구분으로 나눌 수 있습니다. 헤더 부분에서 여러개의 입력변수를 가지고 있는 메소드를 이렇게 표현합니다:
 
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
이 메소드를 다음과 같이 호출합니다:
 
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];
인수 이름은 없습니다. 런타임 시스템에서 메소드 이름은 실제로writeToFile:atomically 입니다.


Accessors

모든 인스턴스 변수들은 Objective-C에서 private가 기본 설정이므로, 여러분들은 거의 대부분의 경우 변수를 얻거나, 설정하기 위해서 accessor(이하 접근자)를 이용해야 합니다. 여기에 두가지 문법이 있습니다. 일단 전통적인 1.x 문법입니다:
 
[photo setCaption:@"Day at the Beach"]; output = [photo caption];
두번째 줄의 코드는 인스턴스 변수를 직접 읽지 않습니다. 이것은 실제로 caption 이라는 이름의 메소드를 호출하는 것입니다. 즉, Objective-C에서는 대부분의 경우 값을 얻기 위해 접두사 "get" 을 붙이지 않아도 됩니다.

언제든지 여러분들은 사각 꺽쇠 안의 코드를 보면 객체 또는 클래스에 메시지를 보내는 것이라고 이해하시면 됩니다.
 

Dot Syntax

Max OS X 10.5 파트의 일부인 Objective-C 2.0 에서 getter와 setter를 위해 dot 문법이 새롭게 등장 했습니다:
 
photo.caption = @"Day at the Beach"; output = photo.caption;
여러분들은 두가지 방법 모두를 사용할 수 있지만 각각의 프로젝트에서 하나의 방법을 사용해야 합니다. dot 문법은 setter와 getter에서만 사용되며, 메소드를 위한 것은 아닙니다.


Creating Objects

객체를 생성하는 두가지 방법이 있습니다. 첫번째 방법은 아래를 보시죠:
 
NSString* myString = [NSString string];
위의 방법은 좀더 편리한 오토매틱 스타일입니다. 이 경우, 여러분들은 autorelease된 객체를  생성할 수 있으며, 좀더 자세한 내용은 나중에 설명하겠습니다. 많은 경우, 여러분들은 메뉴얼 스타일을 이용해서 객체를 생성할 필요가 있습니다:
 
NSString* myString = [[NSString alloc] init];
이것은 중첩된 메소드 호출입니다. 첫번째는 NSString의 alloc 메소드입니다. 이는 메모리를 할당하고 인스턴트 객체를 생성하는 비교적 low-level의 호출입니다.

The second piece is a call to init on the new object. The init implementation usually does basic setup, such as creating instance variables. The details of that are unknown to you as a client of the class.

두번째 부분은 새로운 객체에서 init 하기위한 호출입니다. init 구현은 인스턴스 변수의 생성따위에서 기본적인 셋업을 수행하게 되는데, 그것들에 대한 자세한 사항은 클래스의 클라이언트이기 때문에 여러분들에게는 알려져있지 않습니다.

몇몇의 경우, 여러분들은 입력을 가지는 다른 버전의init을 사용하게 될 수 있습니다:
 
NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];


Basic Memory Management

만일 여러분들이 Max OS X를 위한 어플리케이션을 작업 중이라면, 여러분들은 garbage collection을 사용할 수 있습니다. 일반적으로, 조금더 복잡한 경우가 아니라면 메모리 관리에 대해서 생각하지 않아도 됨을 의미합니다.

그러나, 여러분들은 항상 garbage collection을 지원받을 수 있는 환경이진 않을 것입니다. 이런경우, 여러분들은 몇가지 기본적인 컨셉(개념)을 알 필요가 있습니다.

만일 여러분들이 메뉴얼 alloc 스타일을 이용하여 객체를 생성했다면, 나중에 객체를 해재해줘야 합니다. 오토메틱 스타일로 생성한 객체는 메뉴얼 스타일로 해제하면 안되는데, 그 이유는 그렇게 할 경우 여러분의 어플리케이션이 clash가 발생할 수 있기 때문입니다.

여기에 두가지 예제가 있습니다:
 
// string1 will be released automatically NSString* string1 = [NSString string]; // must release this when done NSString* string2 = [[NSString alloc] init]; [string2 release];
이 튜토리얼을 통해서, 여러분들은 오토매틱 객체가 현재 함수의 끝에서 사라질 것임을 추측할 수 있습니다.

메모리 관리에 대해서 배울것이 더 있지만, 우리가 몇가지 컨셉들을 보고 더 알게된 다음에 배울 것입니다.


Designing a Class Interface

클래스 생성을 위한 Objective-C 문법은 매우 간단합니다. 전형적인 두 파트로 나눠집니다.

클래스 인터페이스는 ClassName.h파일에 담기고, 인터페이스 변수와 퍼블릭 매소드를 정의합니다.

구현부는 ClassName.m 파일 안에 있고, 이 메소드들의 실제 코드가 포함됩니다. 또한 클래스의 클라이언트에서 사용할 수 없는 private 메소드를 정의합니다.

여기에 인터페이스 파일의 예가 있습니다. 클래스 이름이 Photo 라서 파일 이름도 Photo.h 라고 이름지었습니다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } @end
먼저, 우리는 코코아 어플리케이션을 위해서 기본적인 클래스들을 끌어쓰기 위해 Cocoa.h 를 임포트 합니다. #import directive(이하 지시어)는 하나의 파일을 여러번 include 하는 것을 자동으로 방지 해줍니다.

@interface는 이것이 Photo 클래스의 선언이다 라는 것을 말해줍니다. 콜론은 NSObject와 같은 superclass(이하 슈퍼클래스)를 명시할 때 사용합니다.

중괄호 안에는 두개의 인스턴스 변수가 있습니다:caption, photographer. 두개 모두 NSStrings 이지만, id를 포함한 어떤 오브젝트 타입도 될 수 있습니다.

마지막으로, @end 심볼은 클래스 선언의 종료를 의미합니다.
 

Add Methods

인터페이스 변수들를 위한 getter 몇개를 추가 해봅시다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } - caption; - photographer; @end
Objective-C 메소드들은 일반적으로 "get" 접두어를 생략한다는 것을 기억합시다. 메소드 이름 앞의 하나의 '-'는 이것이 인터페이스 메소드이다 라는 것을 의미합니다. 메소드 이름 앞의 '+'는 이것은 클래스 메소드이다 라는 것을 의미합니다.

기본적으로, 컴파일러는 메소드가 하나의 id 객체를 반환할 것이고, 모든 입력 변수들이 id 일것 이라고 추정합니다. 위의 코드는 기술적으로 정확하지만 이것은 흔하지 않습니다. 반환 값을 위한 명확한 타입을 추가해 보겠습니다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } - (NSString*) caption; - (NSString*) photographer; @end
이제 setter를 추가해 봅시다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } - (NSString*) caption; - (NSString*) photographer; - (void) setCaption: (NSString*)input; - (void) setPhotographer: (NSString*)input; @end
setter는 반환값을 필요로 하지 않으므로, 우리는 그것들을 void로 명시합니다.


Class Implementation

구현부를 만들어 봅시다, getter로 시작합니다: 

#import "Photo.h"
@implementation Photo - (NSString*) caption { return caption; } - (NSString*) photographer { return photographer; } @end
코드 중 이 파트는 @implementation 과 클래스 이름으로 시작하고, interface와 같이 @end를 갖습니다. 모든 메소드들은 반드시 두 문장 사이에 있어야 합니다.

코드를 작성 해봤다면 getter는 메우 익숙해 보일 수 있어서, setter의 설명이 조금 더 필요할 것 같습니다:
 
- (void) setCaption: (NSString*)input { [caption autorelease]; caption = [input retain]; } - (void) setPhotographer: (NSString*)input { [photographer autorelease]; photographer = [input retain]; }
각각의 setter는 두개의 변수와 함께 다뤄집니다. 첫번째는 존재하는 객체를 참조하기 위함이고, 두번째는 새로운 입력 객체입니다. garbage collect가 적용된 환경에서 우리는 새로운 값을 직접 설정할 수 있었습니다:
 
- (void) setCaption: (NSString*)input { caption = input; }
하지만 만일 여러분들이 garbage collection을 이용할 수 없다면, 오래된 객체를 해재하고 새로운 것을유지해야 할 필요가 있습니다.

실제로 객체에서 참조를 자유롭게 하는 방법은 해제와 자동해제 두가지가 있다. 일반적인 해제는 참조를 즉시 제거해 준다. 자동해제 메소드는 일정시간 후에 해제를 하지만, 이는 분명히 현재의 함수가 종료 될 때 까지 머무르게 됩니다(만일 여러분들이 이것을 바꾸기 위한 특별한 코드를 작성하지 않았다면).

자동해제 메소드는 setter 안에서 더 안전한데, 이는 새롭고 오래된 값들을 위한 변수들이 같은 객체를 가리킬 수 있기 때문이다. 여러분들은 유지시키고 싶은 오브젝트가 바로 해제되는 것을 원하지 않을 것입니다. 

이러한 개념이 지금은 혼란스러울 수 있지만, 점점 여러분들이 나아가는데 도움이 될 것이다. 지금은 이것을 모두 숙지하지 않아도 됩니다.
 

Init

우리는 인스턴스 변수들을 위해 값들을 초기화는 init 메소들을 만들 수 있습니다:
 
- (id) init { if ( self = [super init] ) { [self setCaption:@"Default Caption"]; [self setPhotographer:@"Default Photographer"]; } return self; }
이것은 매우자명하긴 하지만, 두번째 줄이 아주 조금 낯설어 보입니다. 이것은 하나의 equals sign(=)이고, 이는 [super init]의 결과를 self에 할당하게 됩니다.

이것은 근본적으로 슈퍼클래스가 스스로 초기화 하게 요청하게 됩니다. if 구문은 기본값을 설정하기 전에 초기화가 성공적으로 이루어졌는가를 확인합니다.
 
 

Dealloc

dealloc 메소드는 메모리로 부터 객체가 제거될 때 객체에서 호출됩니다.. 이는 흔히 여러분들의 모든 child 인스턴스 변수들의 참조를 해제하기 위한 최선의 시점입니다.
 
- (void) dealloc { [caption release]; [photographer release]; [super dealloc]; }
첫번째 두 줄은 우리가 각각의 인스턴스 변수들을 해제하기 위해  메시지를 보낸 것입니다. 여기서 자동해제는 필요하지 않으며, 스탠다드 릴리즈가 조금더 빠릅니다.

마지막 줄은 매우 중요합니다. 우리는 수퍼클래스가 클린업하도록 요청하기 위해서 [super dealloc]메시지를 반드시 보내야 합니다. 만약에 우리가 이걸 하지 않으면, 객체는 제거되지 않을 것이고 메모리 누수가 발생할 것입니다.

dealloc 메소드는 grabage collection을 이용할 수 있다면 객체에서 호출하지 않습니다. 대신, 여러분들은finalize 메소드를 실행해야 합니다. 


More on Memory Management

Objecive-C의 메모리 관리 시스템은 reference counting 이라고 부릅니다. 여러분들은 반드시 여러분들의 참조들을 계속 파악하고 있어야하고, 런타임은 메모리를 해제합니다.

이해하기 쉽기 말하자면, 여러분은 어떤때에 객체를alloc 하거나, retain 하는데, 당신이 보낸 각각의 alloc/retain을 위해 하나의 해제를 보냅니다. 그리고 만일 여러분들이 alloc 을 한번, 그리고 retain을 한번 사용했다면, 해제를 두번 해야 합니다.
 
이것이 레퍼런스 카운팅의 이론이지만, 연습에서는 하나의 객체를 생성하기 위한 두가지 이유가 있습니다:

1. 인스턴스 변수를 유지하기 위해
2. 함수안에서 일시적으로 한번 사용하기 위해

대부분의 경우, 인스턴스 변수를 위한 setter는 오래된 객체를 자동 해제하고, 새로운 것을 유지합니다. 그런 후 여러분들은 dealloc 에서 해제가 잘 되었는지 반드시 확인해야 합니다.

그래서 진짜 일은 함수안의 지역 참조들을 관리하는 것입니다. 그리고 거기에는 오직 한가지 규칙이 있습니다: 만일 여러분들이 객체를 alloc 또는 copy와 함께 생성했다면, 해제 또는 자동해제 메시지를 함수의 종료 순간에 보내야 합니다. 다른 방법으로 객체를 선택했다면 그렇게 하지 않아도 됩니다.

인스턴스 변수를 관리하는 첫번째 경우가 여기에 있습니다:
 
- (void) setTotalAmount: (NSNumber*)input { [totalAmount autorelease]; totalAmount = [input retain]; } - (void) dealloc { [totalAmount release]; [super dealloc]; }
여기에 local references의 다른 경우가 있습니다. 우리는 오직 alloc 과 함께 생성된 객체만 해제하면 된다:
 
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75]; NSNumber* value2 = [NSNumber numberWithFloat:14.78]; // only release value1, not value2 [value1 release];
그리고 여기에 콤보가 있습니다: 인스턴스 변수처럼 객체를 설정하기 위한 local reference를 사용하기:
 
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75]; [self setTotal:value1]; NSNumber* value2 = [NSNumber numberWithFloat:14.78]; [self setTotal:value2]; [value1 release];
local reference를 관리하는 규칙은 그것들을 인스턴스 변수로 설정 했는지 하지 않았는지 고려하지 않아도 동일하다. 여러분들은 setter를 어떻게 구현할까에 대해선 생각하지 않아도 됩니다.

여러분들이 이것을 이해한다면, Objective-C의 메모리 관리에 대해 알아야할 부분 중 90%를 이해한 것입니다.


Logging

Objective-C 에서 Logging 메시지를 콘솔에 보내는 것은 매우 단순합니다. 사실, NSLog()가 객체를 위해 %@ 토큰을 추가 했다는 점을 제외하면 C의Printf() 함수와 유사합니다. 
 
NSLog ( @"The current date and time is: %@", [NSDate date] );
여러분들은 콘솔에 객체의 로그를 남길 수 있습니다. NSLog 함수는 객체에서 description 메소드를 호출할 수 있고 반환값을 NSString 으로 찍을 수 있습니다. 여러분들은 커스텀 스트링을 반환하게 하기 위해서 여러분들의 클래스 안의 description 메소드를 override(이하 오버라이드)할 수 있습니다.


Properties

우리가 caption 과 author 를 위해 접근자 메소드를 쓰기 전에 여러분들은 코드가 직관적이고 일반적일 수 있다는 것을 알아차릴 수 있을 것입니다.

Properties 는 우리에게 Objective-C 에서 접근자를 자동으로 만들어낼 수 있게 허락하는 특징을 가지고 있고, 또한 몇가지 다른면으로장점을 가지고 있습니다. properties를 이용하여 Photo 클래스를 컨버팅 해봅시다.

여기에 예전과 같은 모습의 코드가 있습니다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } - (NSString*) caption; - (NSString*) photographer; - (void) setCaption: (NSString*)input; - (void) setPhotographer: (NSString*)input; @end
여기에 properties로 컨버팅된 코드가 있습니다:
 
#import <Cocoa/Cocoa.h> @interface Photo : NSObject { NSString* caption; NSString* photographer; } @property (retain) NSString* caption; @property (retain) NSString* photographer; @end
@property 는 특성을 선언하는 Objective-C 지시자 입니다. 괄호 안의 "retain"은 setter가  입력값을retain 하도록 명시하고, 그리고 나머지 줄은 간단하게 타입과 특성의 이름을 명시합니다.

지금 바로 클래스의 구현부를 봅시다:
 
#import "Photo.h" @implementation Photo @synthesize caption; @synthesize photographer; - (void) dealloc { [caption release]; [photographer release]; [super dealloc]; } @end
@synthesize 지시자는 우리를 위해 자동으로 setter와 getter를 만들어 주므로, 이 클래스를 위해 우리가 해야하는 일은 dealloc 메소드 입니다. 

접근자는 이미지 존재하는 것이 아니라면 생성만 할 수 있으므로, property를 위해 자유롭게 @synthesize를 명시하면 되고, 만일 여러분들이 원한다면 여러분들의 커스텀 getter 또는 setter를 구현할 수 있습니다. 컴파일러는 어느쪽이든 잃어버린 메소드들을 채워 줄 것입니다.

property를 선언하는 많은 다른 방법들이 있지만 이 튜토리얼에서는 다루지 않을 것입니다.
 


Calling Methods on Nil

Objective-C 에서, nil 객체는 다른 많은 언어의 NULL 포인터와 상응하는 기능입니다. 다른 언어와 다른점은 충돌이나, 예외없이 nil 메소드를 호출할 수 있다는 점입니다.

이 테크닉은 프레임워크에서 다양한 방법으로 사용되고 있지만, 이것이 의미하는 가장 중요한 점은 지금 당장 객체에서 메소드를 호출하기 전에 nil을 체크하지 않아도  된다는 것입니다. 만일 여러분들이 객체에서 반환된 nil 메소드를 호출한다면, 여러분들은 반환값으로 nil을 갖게됩니다.

우리는 또한 이것을 우리의 deallc 메소드를 개선시키는 것에 이용할 수 있습니다:
 
- (void) dealloc { self.caption = nil; self.photographer = nil; [super dealloc]; }
이렇게 해도 작동하는데 이는 우리가 인스턴스 변수로 nil을 설정 했을 때 setter는 nil을 retain 하고 오래된 값을 release 하기 때문입니다. 이러한 접근은 종종 dealloc 보다 나은데 왜냐하면 변수가 있었던 객체의 랜덤데이터를 가리킬 염려가 없기 때문입니다.

우리는 self.<var> 문법을 이용하고 있다는 점을 명심하십시오. 이는 우리가 setter를 이용하고 있다는 것과 메모리 관리를 자유롭게 이용하는 것을 의미하고 있습니다. 만일 우리가 아래와 같이 값을 직접 설정하면 메모리 누수가 발생 할 것이다:
 
// incorrect. causes a memory leak. // use self.caption to go through setter caption = nil;


Categories

Categories는 Objective-C에서 가장 유용한 특징입니다. 요점만 말하자면, 카테고리는 존재하는 클래스에 서브클래스 없이, 또는 그것들이 어떻게 구현되었나에 대한 자세한 정보를 알 필요 없이 메소드를 추가할 수 있도록 허락 해줍니다.

만들어진 객체에 메소드를 추가할 수 있기 때문에 이것은 매우 유용합니다. 만일 여러분들이 여러분들의 어플리케이션 안에서 NSString의 모든 인스턴스에 메소드를 추가하기를 원하다면, 단지 하나의 카테고리를 추가하기만 하면 됩니다. 커스텀 서브클래스를 사용하기 위해서 모든것을 가질 필요가 없습니다.

예를들면, 컨텐츠가 URL인지 확인하기 위해 NSString에 메소드를 추가를 원한다면 저는 이렇게 구현할 것입니다:
 
#import <Cocoa/Cocoa.h> @interface NSString (Utilities) - (BOOL) isURL; @end
이건 클래스를 선언하는 모습과 매우 습사합니다. 다른점은 수퍼클래스의 리스트가 없고, 괄호에 카테고리를 위한 이름이 있다는 것입니다. 이름은 여러분들이 원하는 무엇이는지 될 수 있지만, 안에 있는 메소드와 커뮤니케이션 해야합니다.

여기에 구현부가 있습니다. 이 예가 URL 검출의 좋은 구현예는 아니지만, 우리는 카테고리에 대한 컨셉을 배우는 것에 중점을 둡시다:
 
#import "NSString-Utilities.h" @implementation NSString (Utilities) - (BOOL) isURL { if ( [self hasPrefix:@"http://"] ) return YES; else return NO; } @end
이제 여러분은 어떤 NSString 에서도 이 메소드를 사용할 수 있습니다. 아래의 코드는 "string1 is a URL"을 콘솔에 출력할 것 입니다:
 
NSString* string1 = @"http://pixar.com/"; NSString* string2 = @"Pixar"; if ( [string1 isURL] ) NSLog (@"string1 is a URL"); if ( [string2 isURL] ) NSLog (@"string2 is a URL");
서브클래스와 다르게, 카테고리는 인스턴스 변수를 추가할 수 없습니다. 하지만, 클래스 안에 이미 존재하는 메소드를 오버라이드(override)하기 위해 카테고리를 이용할 수 있지만, 매우 조심해야 합니다.

기억해야 합니다, 여러분들이 카테고리를 이용해서 클래스로 변경시킬 경우에, 이것은 어플리케이션 전체에 걸친 클래스의 모든 인스턴스에 영향을 줄 수 있습니다.


Wrap Up

이것은 Objective-C의 기본적인 개요입니다. 다른 언어를 경험한적이 있다면 매우 쉽게 익힐 수 있습니다. 특별한 문법을 배우기 위해서는 충분하지 않으며, Cocoa 전반에 걸쳐 같은 예제가 계속해서 사용되었습니다.

여러분들이 이 예제들을 실행해 보고 싶으시다면, 아래의 프로젝트를 다운로드 받으시고, 소스 코드를 살펴 보십시오:
LearnObjectiveC Xcode 3.0 Project (56k)
 
고맙습니다.


긴 번역이 끝났습니다. 서둘러 번역하느라, 이해하지 못한 부분도 있어서 어떤 부분은 반쪽짜리 번역이 되어 버렸네요. 한번 번역으로 끝나지 않고, 지속적인 모니터링을 통해서 퇴고해나갈 예정입니다.

위 글은 Objective-C에 대한 기본적인 개념들의 개요를 간단한 예제를 통해 소개하고 있는데요, 객체에 대한 좀더 자세한 설명이 서두에 있었으면 하는 아쉬움이 남습니다.

그래서 다음에 기회가 되면, 
Objective-C 에서 객체, 클래스, 인터페이스, 메소드 등에대한 이야기를 해볼까 합니다. 그 글이 완료되면 이 포스팅에도 링크를 걸어둘테니 관심 있으신 분들은 가끔씩 생각나실때 보시면 될 듯 합니다.

미숙한 번역 포스팅이 노력하시는 분에게 작은 도움이 되었으면 좋겠네요.
즐거운 하루 되세요 : )


http://snowhouse-textcube.blogspot.kr/2010/01/%EC%95%84%EC%9D%B4%ED%8F%B0-%EA%B0%9C%EB%B0%9C-%EC%99%84%EC%A0%84-%EC%B4%88%EB%B3%B4%EB%8F%84-%EB%B3%B4%EB%8A%94-objective-c-%EA%B8%B0%EC%B4%88%EA%B0%9C%EB%85%90.html

+ Recent posts