0. 들어가기 전에
Objective-C 공부를 위하여 기본적으로 "프로그래밍 오브젝티브 C 2.0 Programing"(스티브 코찬)을 텍스트로 하였다.
![]() |
|
책의 내용은 C에서 사용되는 기본 내용도 포함하고 있어 C/C++ 에 익숙한 사람에게는 지루할 수 있으나 기초부터 접근하는 사람에게는 좋은 책으로 보여집니다.
본 블로그에 내용은 위 책의 목차를 기본으로 진행하며, 추가적으로 공부해야 할 부분이나 짧게 설명된 부분들은 웹이나 다른 도서를 참고하여 진행했습니다.
1. Objective-C 역사
- 1980년대 초 브래드 콕스(Brad J. Cox)와 톰 러브(Tom Love)가 Objective-C 언어 설계.
- C 언어위에 계층적(layered)으로 올려진 구조로 객체를 사용할 수 있도록 함(Small Talk로부터 아이디어 얻음).
- 초기 모델은 OOPC(Object-Oriented Pre-Compiler)라 불리우는 C언어 기반의 Smalltalk 프리컴파일러 형태였다.
- Cox와 Love는 PPI를 설립하고 OOPC를 사용함(이후 StepStone으로 이름을 바꿈)
- 1988년 스티브 잡스가 창업한 NeXT Software가 StepStone으로부터 라이센스 받아 NEXTSTEP 개발환경, 라이브러리 개발
- 1992년 GNU 개발 환경에 Objective-C 지원 추가, GPL(General Public License)로 배포
- 1994년 NeXT Computer 와 썬마이크로시스템즈가 OPENSTEP 발표
- FSF(Free Software Foundation) 에서는 GNUStep으로 배포, Linux 버전은 LinuxStep으로 불림
- 1996년 Apple이 NeXT Software를 인수하고 OS X 의 근간으로 사용
- 2007년 Objective-C 2.0 으로 업데이트 함.
본 내용에서는 언어의 기본 용법과 일반적으로 사용되는 Foundation Framework 에서의 사용법을 알아 볼 것이다.
2. Syntax
- C의 Thin Layer 이며 Superset으로 볼 수 있다.
- C Program 도 Objective-C Compiler에서 컴파일 가능
- Objective-C Class에 C code 도 추가 가능
- Object는 Smalltalk의 문법을 따르며 그외의 문법(variables, pre-processing, expressions, function declarations and function call)은 C를 따른다.
- 객체지향 형태는 Smalltalk-style messaging 방식으로 구현 되었다.
3. Messages
- Objective-C는 객체 instance간의 message passing 방식으로 동작한다.
- 메소드를 콜(call a method)하는 것이 아니라 메세지를 보내는(send a message) 방식이다.
- Simula-style 은 컴파일 타임에 method name 이 결정되지만 Smalltalk-style 에서는 runtime 시에 결정된다.
obj->method(argument); // in C++
[obj method:argument]; // in Objective-C
Simula-Style
장점: 다중 상속을 허용하며 컴파일 타임 바인딩으로 빠른 실행을 보장한다.
단점: 기본적으로 동적 바인딩을 지원하지 않아 추상화 되어 있음에도 모든 메소드는 구현과 일치한다.
Smalltalk-Style(Message passing style)
장점: 아직 구현되지 않은 메소드에 메세지를 보낼수 있다.(run-time 에결정)
컴파일 타임에 object는 정의되지 않아도 error가 발생하지 않는다.
4. Interface and Implementations
- class의 선언부는 interface 로 header file (.h) 에 선언한다.
@interface ClassName: SuperClassName {
// instance variable
}
+ classMethod;
- (return-type)classMethod2:(param1_type)paramName1 Param2CallName:(param2_type)param2_name;
@end
....
[obj classMethod2:param1 Param2CallName:param2];
- (+) 는 class methods를 나타낸다. (static method in C++)
- (-) 는 instance methods를 나타낸다. (public method in C++)
위의 코드를 C++에서 표현하면 다음과 같다.
class ClassName: public SuperClassName {
protected:
//instance variable
public:
static void* classMethod();
static return-type classMethod2(param1_type paramName1, param2_type param2_name=default);
}
- class의 구현부는 implementation 로 method file (.m) 에 선언한다.
@implementation ClassName
+(return-type)classMethod {
// implementation
}
-(return-type)instanceMethod {
// implementation
}
@end
5. 인스턴스화(Instantiation)
Objective-C 에서는 할당(allocation)과 초기화(initiation) 두단계를 거쳐야 비로소 인스턴스화가 된다.
MyObject *o = [[MyObject alloc] init]; // 두 단계를 거쳐 초기화 진행
MyObject *o = [[MyObject alloc] initWithString: myString]; // init 은 paramater를 받는 방식으로 변경 가능
MyObject *o = [MyObject new]; // 초기화 까지 진행하지만 추천하지 않는다.
init함수는 일반적으로 다음과 같이 구성된다.
-(id) init {
self = [super init];
if(self) {
// perform initialization of object here
}
return self;
}
6. Protocol
Objective-C 가 소개되었을때 다중 상속(multiple inheritance)가 표준에 들어 있었지만 구현되지 못하고 protocol 을 만들었다.
Java나 C# 의 "interface" 와 같은 기능으로 informal protocol 과 formal protocol 이 있다.
informal protocol: 클래스가 구현하거나 하지 않아도 되는 메소드의 리스트다.
formal protocol: 클래스가 반드시 구현해야 하는 메소드 리스트로 컴파일러에의해 강제된다. 즉, 구현하지 않으면 에러가 발생.
@ protocol NSLocking
- (void) lock;
- (void) unlock;
@end
@ interface NSLock : NSObject <NSLocking>
// ....
@end
7. Forwarding
- Objective-C는 메세지를 보낸다고(sending) 한다.
- 메세지에 대한 응답도 전달(Forwarding)한다고 한다.
- 메세지 전달은 Observer Pattern 이나 Proxy Pattern 과 같은 Design Pattern 으로 구현 될 수 있다.
- Objective-C에서는 객체를 위해 다음과 같은 한쌍의 메소드를 제공한다.
- Forwarding Methods
- (retval_t)forward:(SEL)sel args:(arglist_t)args; // with GCC
- (id)forward:(SEL)sel args:(marg_list)args; // with NeXT/Apple systems
- Action Methods
- (retval_t)performv:(SEL)sel args:(arglist_t)args; // with GCC
- (id)performv:(SEL)sel args:(marg_list)args; // with NeXT/Apple systems
- OpenStep, Cocoa, and GNUstep은 Object class를 사용하지 않는다. NSObjective에서는
- (void)forwardInvocation:(NSInvocation*)anInvocation 을 사용하여 forwarding 한다.
다음 예제를 보고 개념을 이해하자. (OpenStep으로 테스트 결과 동작하지 않았다.)
Forwarder.h
# import <objc/Object.h>
@interface Forwarder : Object { id recipient; //The object we want to forward the message to. } //Accessor methods. - (id)recipient; - (id)setRecipient:(id)_recipient;
@end
Forwarder.m
# import "Forwarder.h"
@implementation Forwarder - (retval_t)forward:(SEL)sel args:(arglist_t) args { /* * Check whether the recipient actually responds to the message. * This may or may not be desirable, for example, if a recipient * in turn does not respond to the message, it might do forwarding * itself. */ if([recipient respondsToSelector:sel]) { return [recipient performv:sel args:args]; } else { return [self error:"Recipient does not respond"]; } } - (id)setRecipient:(id)_recipient { [recipient autorelease]; recipient = [_recipient retain]; return self; } - (id) recipient { return recipient; } @end
Recipient.h
# import <objc/Object.h>
// A simple Recipient object. @interface Recipient : Object - (id)hello; @end
Recipient.m
# import "Recipient.h"
@implementation Recipient - (id)hello { printf("Recipient says hello!\n"); return self; } @end
main.m
# import "Forwarder.h" # import "Recipient.h" int main(void) { Forwarder *forwarder = [Forwarder new]; Recipient *recipient = [Recipient new]; [forwarder setRecipient:recipient]; //Set the recipient. /* * Observe forwarder does not respond to a hello message! It will * be forwarded. All unrecognized methods will be forwarded to * the recipient * (if the recipient responds to them, as written in the Forwarder) */ [forwarder hello]; [recipient release]; [forwarder release]; return 0;
}
iOS의 동작 방법은 Apple의 developer page를 참조하자.
8. Category
- Objective-C 설계시 부터 유지보수성이 주요 관심사 였다.
- 이를 위해 Smalltalk 의 categories 개념을 가져와 확장하였다.
- 클래스의 소스나 재 컴파일 없이 기존 클래스에 category 만 추가해서 새로운 함수를 추가 할 수 있다.
- 기존 클래스의 method signature(리턴, 파라메터가 완전히)가 같은 함수를 정의 할 수도 있으며, 이때 category의 함수가 사용되어 진다.
다음 예제는 Integer 클래스에 새 카테고리로 Arithemtic 으로 정의하고 두개의 함수를 추가한 내용이다.
# import "Integer.h" @interface Integer (Arithmetic) - (id) add: (Integer *) addend; - (id) sub: (Integer *) subtrahend;
@end
실행파일은 다음과 같이 정의 된다.
# import "Arithmetic.h" @implementation Integer (Arithmetic) - (id) add: (Integer *) addend { return [self integer: [self integer] + [addend integer]]; } - (id) sub: (Integer *) subtrahend { return [self integer: [self integer] - [subtrahend integer]]; }
@end
Objective-C의 전체적인 특성을 알아보았다.
다음부터는 각각의 내용들을 자세히 알아보자
본 내용은 Wiki의 Objectivce-C 페이지를 참조하였습니다.( http://en.wikipedia.org/wiki/Objective-C )
'디지털 양피지 > Objective-C' 카테고리의 다른 글
Objective-C: 클래스 더 알아보기 (0) | 2013.06.05 |
---|---|
Objective-C: 클래스, 객체, 메서드, 데이터 형과 표현식 (0) | 2013.05.04 |
Objective-C: Objective-C로 프로그래밍 하기(On Windows) (0) | 2013.05.04 |