오브젝티브-C
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
오브젝티브-C는 1980년대 초 브래드 콕스와 톰 러브가 개발한 객체 지향 프로그래밍 언어이다. C 언어를 기반으로 스몰토크의 객체 지향 기능을 결합하여, C의 유연성과 스몰토크의 객체 지향성을 함께 제공한다. 1980년대 중반 스티브 잡스가 NeXT 컴퓨터의 운영체제에 채택하면서 널리 알려졌고, 애플의 macOS와 iOS 개발 환경에서 핵심 언어로 사용되었다. Objective-C 2.0에서는 가비지 컬렉션, 프로퍼티, 빠른 열거 기능이 추가되었으며, 이후 자동 참조 카운팅(ARC)이 도입되어 메모리 관리를 간소화했다. Objective-C는 Objective-C++, mulle-objc, Portable Object Compiler 등의 변종이 존재하며, Cocoa, GNUstep 등의 라이브러리와 함께 사용된다.
더 읽어볼만한 페이지
- 1986년 개발된 프로그래밍 언어 - 오베론 (프로그래밍 언어)
오베론은 니클라우스 비르트가 설계한 프로그래밍 언어로, 단순성을 추구하며 라이브러리 개념을 강조하고 엄격한 타입 검사 등으로 안정성을 높였으며, 후속 버전에서는 객체 지향 프로그래밍 기능이 추가되었다. - 1986년 개발된 프로그래밍 언어 - 얼랭
얼랭은 통신 애플리케이션 개발을 위해 설계된 함수형 프로그래밍 언어로, 동시성 및 분산 처리 지원이 강력하며 오류에 강한 시스템 구축에 유용하여 다양한 분야에서 활용되고 있다. - GNUstep - 번들 (macOS)
macOS에서 번들은 응용 프로그램, 프레임워크, 플러그인 등 다양한 형태로 존재하며 실행에 필요한 코드, 리소스, 설정 파일 등을 포함하는 특수한 디렉터리 형식이다. - GNUstep - 윈도 메이커
윈도 메이커는 브라질 프로그래머 알프레두 코지마가 개발한 GNUstep용 윈도우 매니저로, NeXTSTEP의 GUI를 모방하며, 독(Dock) 기능을 제공하고, 작고 빠른 성능으로 다양한 리눅스 배포판에서 사용할 수 있다. - NeXT - 스티브 잡스
스티브 잡스는 애플의 공동 창업자이자 CEO, 픽사의 CEO, 디즈니의 이사회 멤버로서, 혁신적인 기술과 디자인으로 정보기술 산업에 큰 영향을 미친 미국의 기업인이다. - NeXT - NeXTSTEP
NeXTSTEP은 NeXT에서 개발한 마하 커널 기반의 유닉스 계열 운영 체제로, BSD 소스 코드를 포함하며 디스플레이 포스트스크립트, 독점적인 창 관리 엔진, Objective-C 언어 및 런타임 환경을 제공하고 현대적인 운영체제 인터페이스 발전에 기여하여 macOS의 기반이 되었으며 최초의 웹 브라우저와 앱 스토어 개발에 영향을 미쳤다.
오브젝티브-C - [IT 관련 정보]에 관한 문서 | |
---|---|
기본 정보 | |
이름 | Objective-C |
파일 확장자 | .h, .m, .mm, .M |
설계자 | 브래드 콕스, 톰 러브 |
발표 연도 | 1984년 |
유형 | 정적 타이핑, 동적 타이핑, 강한 형 체계, 약한 형 체계 |
특징 | |
패러다임 | 반영형, 클래스 기반, 객체 지향 |
영향 받은 언어 | C, 스몰토크 |
영향을 준 언어 | Groovy, Java, Nu, Objective-J, TOM, Swift |
구현 및 사용 환경 | |
구현체 | Clang, GCC |
운영 체제 | 크로스 플랫폼 |
기타 | |
웹사이트 | developer.apple.com |
2. 역사
1980년대 초, 브래드 콕스와 톰 러브는 소프트웨어 개발에서 재사용성 문제를 해결하기 위해 오브젝티브-C를 개발했다. 이들은 스몰토크의 영향을 받아 C 언어에 객체 지향 기능을 추가한 OOPC를 만들었다. 이후 이들은 프로덕티비티 프로덕츠 인터네셔널(Productivity Products International; PPI)이라는 회사를 설립하여 오브젝티브-C 컴파일러와 라이브러리를 상업적으로 판매했다. 1986년에는 콕스가 "객체 지향 프로그래밍"(Object-Oriented Programming, An Evolutionary Approach)을 출간하여 오브젝티브-C의 개념을 널리 알렸다.[5]
1985년 스티브 잡스가 설립한 넥스트는 1988년 스텝스톤(StepStone, PPI의 새 이름)으로부터 오브젝티브-C 라이선스를 획득하고, GNU 컴파일러 모음을 확장하여 오브젝티브-C를 지원하도록 했다. 넥스트는 넥스트스텝 개발 환경의 핵심 언어로 오브젝티브-C를 채택하고, 앱키트(AppKit)와 파운데이션 키트(Foundation Kit) 등의 라이브러리를 개발했다.
1996년 애플이 넥스트를 인수하면서 오브젝티브-C는 macOS X의 핵심 언어가 되었으며, Cocoa API의 기반이 되었다. 애플은 오브젝티브-C를 지속적으로 발전시켜 Mac OS X v10.5부터는 '''Objective-C 2.0'''을 발표했다.
GNU 프로젝트는 오픈스텝 표준을 기반으로 코코아의 자유 소프트웨어 구현인 GNUstep을 개발했다.[10]
2. 1. 초기 역사
1980년대 초, 소프트웨어 공학의 일반적인 관행은 구조적 프로그래밍이었다. 하지만 문제 규모가 커짐에 따라 구조적 프로그래밍 기법은 한계를 드러냈다. 브래드 콕스와 톰 러브는 스몰토크라는 프로그래밍 언어에서 이 문제에 대한 해답을 찾고자 했다. 스몰토크는 객체 지향 프로그래밍을 지원하는 언어였지만, 가상 머신을 사용한다는 단점이 있었다.콕스와 러브는 C 언어에 스몰토크의 기능을 추가하기 시작했고, OOPC라고 불리는 C의 객체 지향 버전을 내놓았다. 1986년, 콕스는 "객체 지향 프로그래밍"(Object-Oriented Programming, An Evolutionary Approach)를 출간하여 Objective-C의 명세를 담았다.[5]
2. 2. NeXT로 인기를 얻다
스티브 잡스는 애플을 떠난 후, 넥스트라는 회사를 설립했다. 1988년, 넥스트는 스텝스톤(StepStone; 오브젝티브-C의 상표권자)에게 오브젝티브-C의 사용 허가를 받고, 오브젝티브-C를 지원하기 위하여 GNU 컴파일러 모음을 확장하고, 넥스트스텝 사용자 인터페이스와 인터페이스 빌더를 구축하는 데 쓰일 앱키트(AppKit)와 파운데이션 키트(Foundation Kit)를 개발했다.[9] 비록 넥스트가 내놓은 워크스테이션들은 시장에 큰 영향을 주지 못했지만, 이 툴들은 업계에 널리 퍼졌다. 결국 넥스트는 하드웨어 제작을 포기하고 소프트웨어 툴에 집중하여 넥스트스텝 (및 오픈스텝)을 독립적인 사용자 프로그래밍 환경으로 판매하기 시작했다.GNU는 오픈스텝 표준을 기반으로 넥스트스텝의 무료 버전을 구축하려는 그누스텝(GNUstep) 프로젝트를 시작했다.[10] 1992년 데니스 글래팅(Dennis Glatting)이 GNU 오브젝티브-C의 런타임을 처음으로 작성했다. 1993년 이후로는 크레스텐 크랩 토룹(Kresten Krab Thorup)이 덴마크에서 대학생 시절에 만든 런타임이 널리 쓰였다.[11] 토룹은 1993년부터 1996년까지 넥스트에서 일했다.
2. 3. 애플에 인수 및 발전
1996년 넥스트는 애플에 합병되었고, 오브젝티브-C는 macOS X의 기반이 되는 Cocoa API의 핵심 언어가 되었다. 애플의 현재 Cocoa API의 대부분은 오픈스텝 인터페이스 객체를 기반으로 하며, 현재 개발에 사용되는 가장 중요한 오브젝티브-C 환경이다.[11]애플은 오브젝티브-C를 지속적으로 발전시켜 왔고, Mac OS X v10.5부터 일부 언어 사양을 변경하여 '''Objective-C 2.0'''이라고 부른다.
2014년 WWDC에서 애플은 "C가 없는 Objective-C"로 특징지어지는 새로운 언어인 Swift를 발표했다.[59]
3. 문법
Objective-C는 C 언어의 '엄격한' 상위집합으로, 모든 C 프로그램은 Objective-C로 컴파일 가능하며 프로그램의 의미도 양 언어가 동일하다. Objective-C는 C 언어와 스몰토크 양쪽에서 유래한 문법을 사용한다. 전처리, 표기, 함수 선언, 함수 호출 등은 C 언어의 문법을 따르고, 객체 지향적인 기능들은 스몰토크 방식의 메시지 전달을 통해 구현된다.[12][13][14][15][16][17]
C++(C++)와는 달리 다중 상속을 지원하지 않으며, 그 대신 자바의 인터페이스에 해당하는 프로토콜(protocol)을 정의할 수 있다. 또한 카테고리(category)를 통해 기존 클래스에 새로운 메쏘드를 추가함으로써 클래스의 기능을 확장할 수 있는데, 이는 상속을 통해서만 기능을 확장할 수 있는 대다수의 객체 지향 언어와 크게 구별되는 특성이다. C++나 자바 등과는 달리 객체에 대해서 완전한 동적 형 변환(dynamic typing)을 지원한다.
Objective-C는 C를 확장하여 객체 지향을 가능하게 했다기보다는, C로 작성된 객체 지향 시스템을 제어하기 쉽도록 매크로적인 확장을 가한 언어이다. 따라서, "better C"로 나아간 C++(C++)와는 달리, "C & Object System"이라는 생각이며, 어떤 의미에서는 두 개의 언어가 혼재된 상태에 있다.
함수(메서드)의 정의와 호출 방법이 독특하기 때문에, Objective-C의 코드는 언뜻 C++ 이상으로 C와는 동떨어진 독특한 기술이 된다. 그러나 언어 사양은 C의 완전 상위 호환이며, if/for/while 등의 제어문이나 int 등의 스칼라형, 함수 표기법, 선언·대입과 같은 기본적인 문법은 C에 준한다. 한편 객체 시스템은 Smalltalk의 개념을 거의 그대로 차용한 것으로, 동적 타입의 클래스형 객체 지향 런타임을 가지며, 메시지 패싱에 의해 동작한다. 이 때문에 종종 "인라인으로 C를 쓸 수 있는 Smalltalk" 또는 "인라인으로 Smalltalk를 쓸 수 있는 C" 등으로 불린다. C와는 다른 Objective-C 특유의 부분은 @
로 시작하는 '''컴파일러 지시자'''로 명시되며, 객체의 메서드 호출은 [
]
로 둘러싸인 '''메시지 표현식'''으로 수행된다.
최대 특징은 객체 시스템이 완전히 동적이라는 점으로, 실행 시 클래스 확장, 객체 범용형 id의 도입에 의해 타입에 구애받지 않는 동적 배열·사전 등, 인터프리터에 가까운 기술력을 갖추고 있다. 실제로 코드 자체는 네이티브 컴파일되지만, 동작 원리는 거의 인터프리터에 가깝고, 컴파일러형 언어로는 드문 유연성을 발휘한다.
C 측에서 보면 일종의 스크립트 인터프리터가 얹혀있는 상태이며, 반대로 객체 시스템에서는 OS 기능과 방대한 C 언어 자원을 직접 이용 가능한 인터페이스가 갖춰져 있다고 할 수 있다. 또한 가상 머신을 가질 필요가 없기 때문에, 다루기도 좋다. 성능은 Java와 같은 중간 코드형 언어보다 우수하며, C나 C++와 같은 네이티브 컴파일 언어에는 미치지 못하는 것으로 알려져 있다. Objective-C 특유의 이러한 형태는 양쪽의 장단점이 명확하며, 실제적인 사용성이 매우 뛰어나다. 이러한 특성에 주목한 것이 NEXTSTEP으로, UNIX와의 호환성과 선진적인 객체 지향 환경의 양립에 성공했으며, 이후 OS 설계에 큰 영향을 미치게 되었다.
후속 언어에 미친 영향으로는, 특히 Java의 기초 설계에서 그 모습을 볼 수 있다(썬 마이크로시스템즈(Sun Microsystems)가 OPENSTEP 개발을 공동으로 진행했다는 것과 관련이 있다[58]).
클래스 | 단일 상속 + 인터페이스 다중 상속(프로토콜) 보통은 루트 클래스에서 상속 |
---|---|
객체 시스템 | 동적 바인딩, 메타클래스를 가짐 |
타입 | 동적 타입 + 외형상의 정적 타입의 하이브리드 |
실행 속도 | 코드는 C와 동등한 네이티브 컴파일, 메서드 호출은 동적 디스패치를 수행하므로 약간 지연된다. 평균적으로 C/C++보다 다소 느리고, 중간 코드형 언어(Java 등)보다 수 배 정도 빠르다고 한다. 다만, 중요한 부분은 언제든지 C로 다시 작성할 수 있으므로, 실행 속도가 문제가 되는 경우는 거의 없다. |
기타 | 객체는 포인터 호환, C의 스칼라형은 객체가 아님 |
C 언어에서 `#include
` 전처리 지시어는 항상 해당 지점에서 파일의 내용을 소스에 삽입한다. Objective-C에는 `#import
` 지시어가 있는데, 각 파일이 컴파일 단위당 한 번만 포함된다는 점을 제외하면 `#include
`와 동일하며, 이로 인해 include 가드가 필요하지 않다.
3. 1. 메시지
Objective-C의 객체 지향 프로그래밍 모델은 객체 인스턴스에 메시지를 전달하는 방식을 기반으로 한다. 이는 C++(C++)에서 사용되는 Simula 스타일 프로그래밍 모델과는 다르다. Objective-C에서는 '메서드를 호출'하는 것이 아니라 '메시지를 보낸다'.[18] C++에서는 `obj->method(argument);`와 같이 작성하는 코드를 Objective-C에서는 `[obj method:argument];`와 같이 작성한다.Objective-C는 동적 타이핑을 사용한다. 이는 모든 메소드가 사전에 정의되어야만 호출이 가능한 C++이나 자바와 같은 정적·명시적 형 변환을 사용하는 언어와 다른 점이다. C++와 다르게 가상함수의 선언없이 자바와 같이 자식클래스에서 메소드를 오버라이딩 하는 것만으로 다형성이 제공된다.
메시지 전달은 런타임 시의 메시지 패싱이며, 이때 전달되는 메시지 값을 셀렉터라고 한다. 스몰토크와 마찬가지로 키워드 인자 형식을 취하며, 셀렉터 이름과 인자 값이 번갈아 나열되는 형태가 된다.
```objc
// 메시지 전송
// 단항 메시지
[수신자 msg];
// 인자 포함 메시지. 이 경우 "msg:with:"로 셀렉터 하나
val = [수신자 msg: arg1 with: arg2];
// 메시지 중첩
val = [obj1 msg: [obj2 msg]];
```
구현 방식에 따라, 존재하지 않는 메서드를 호출했을 때 예외가 발생하기 전에 해당 호출을 다른 객체로 전달할 기회가 주어진다. 이를 메시지 포워딩이라고 한다.
3. 2. 클래스의 선언과 구현
C++(C++)와 비슷하게 클래스의 선언과 구현은 헤더 파일과 소스 파일로 나뉜다. 헤더 파일의 확장자는 .h로 동일하나, 소스 파일의 확장자는 .c나 .cpp가 아닌 .m (C에 대응) 또는 .mm (C++에 대응)이다.[63] 확장자가 .m 또는 .mm으로 정해진 이유는 단지 .o와 .c가 C에 의해 사용되고 있었기 때문이다.[63]클래스의 선언은 `@interface`로 시작하고 `@end`로 끝난다. `+` 기호는 클래스 메서드를, `-` 기호는 인스턴스 메서드를 뜻한다. 클래스 메서드는 인스턴스 변수에 접근할 수 없다. 메서드에 매개변수가 있을 경우 일반적인 프로그래밍 언어와 다르게 괄호 대신 콜론으로 구분한다. 변수가 2개 이상일 경우 각 변수의 역할을 나타내는 라벨을 붙여준다.
Objective-C는 클래스의 인터페이스와 구현을 별도로 선언된 코드 블록에 넣도록 요구한다. 관례적으로 개발자는 인터페이스를 헤더 파일에, 구현을 코드 파일에 넣는다. 이는 C++(C++)나 파이썬(Python)과 같은 다른 객체 지향 언어에서 사용되는 클래스 선언과 유사하다.
인터페이스 정의에서 파생된 ''카테고리''는 기존 클래스에 메서드를 추가할 수 있다.[22]
3. 2. 1. 선언(Interface)
C++와 비슷하게 클래스의 선언과 구현은 헤더파일과 소스파일로 나뉜다. 헤더파일의 확장자는 .h로 동일하나 소스파일의 확장자는 .c나 .cpp가 아닌 .m(.c 에 대응) 또는 .mm(.cpp 에 대응)이다. 확장자가 .m 또는 .mm으로 정해진 이유는 단지 .o와 .c가 C에 의해 사용되고 있었기 때문이다.[63]선언(interface)은 클래스의 기본적인 구조를 열거하는 것이며, 일반적으로 헤더파일 .h에 기록된다.
```objc
@interface classname : superclassname // 부모클래스 이름
{
// 클래스 변수
}
+ classMethod1; // 클래스 메소드
+ (return_type)classMethod2;
+ (return_type)classMethod3:(param1_type)param1_varName;
- (return_type)instanceMethod1:(param1_type)param1_varName :(param2_type)param2_varName; // 인스턴스 메소드
- (return_type)instanceMethod2WithParameter:(param1_type)param1_varName andOtherParameter:(param2_type)param2_varName;
@end
```
클래스의 선언은 @interface로 시작하고 @end로 끝난다. +기호는 클래스 메소드를 뜻한다. 자바의 정적메소드와 동일하며, 선언된 클래스의 인스턴스의 유무에 상관없이 항상 존재한다. 클래스 메소드는 클래스 변수에 대한 접근권한이 없다. -기호는 인스턴스 메소드이며 클래스가 인스턴스화가 되어야만 사용할 수 있다.
메소드에 매개변수가 있을 경우 일반적인 프로그래밍 언어와 다르게 괄호대신 콜론으로 구분한다. 변수가 2개 이상일 경우 그 해당 변수가 무슨 역할을 하는지 라벨을 따로 붙여준다. 이 레이블은 코드를 더 읽기 쉽게 도와준다.
```objc
- (void)setRangeStart:(int)start end:(int)end;
- (void)setWithLatename:(NSString *)last firstname:(NSString *)first middlename:(NSString *)middle;
```
실제 코드 상에선 다음과 같이 호출된다.
```objc
[setRangeStart:4 end:10];
[setWithLatename:@"Last" firstname:@"First" middlename:@"Middle"];
```
Objective-C는 클래스의 인터페이스와 구현을 별도로 선언된 코드 블록에 넣도록 요구한다. 관례적으로 개발자는 인터페이스를 헤더 파일에, 구현을 코드 파일에 넣는다. 일반적으로 .h로 끝나는 헤더 파일은 C 헤더 파일과 유사하며, 일반적으로 .m으로 끝나는 구현(메서드) 파일은 C 코드 파일과 매우 유사할 수 있다.
이는 C++(C++)나 파이썬(Python)과 같은 다른 객체 지향 언어에서 사용되는 클래스 선언과 유사하다.
클래스의 인터페이스는 일반적으로 헤더 파일에 정의된다. 일반적인 규칙은 헤더 파일의 이름을 클래스 이름으로 지정하는 것이다.
인터페이스 선언은 다음과 같은 형식을 취한다.
```objc
@interface classname : superclassname {
// 인스턴스 변수
}
+ classMethod1;
+ (return_type)classMethod2;
+ (return_type)classMethod3:(param1_type)param1_varName;
- (return_type)instanceMethod1With1Parameter:(param1_type)param1_varName;
- (return_type)instanceMethod2With2Parameters:(param1_type)param1_varName
param2_callName:(param2_type)param2_varName;
@end
```
위에서 더하기 기호는 클래스 자체에서 호출할 수 있는 클래스 메서드를 나타내고, 빼기 기호는 클래스의 특정 인스턴스에서만 호출할 수 있는 인스턴스 메서드를 나타낸다. 클래스 메서드는 인스턴스 변수에 접근할 수 없다.
위의 코드는 다음과 같은 C++(C++) 인터페이스와 대략적으로 동일하다.
```cpp
class classname : public superclassname {
protected:
// 인스턴스 변수
public:
// 클래스 (정적) 함수
static void *classMethod1();
static return_type classMethod2();
static return_type classMethod3(param1_type param1_varName);
// 인스턴스 (멤버) 함수
return_type instanceMethod1With1Parameter(param1_type param1_varName);
return_type
instanceMethod2With2Parameters(param1_type param1_varName,
param2_type param2_varName = default);
};
```
`instanceMethod2With2Parameters:param2_callName:`는 C/C++에는 직접적인 해당 항목이 없는 선택자 세그먼트와 인수 표현식의 인터리빙을 보여준다.
반환 유형은 모든 표준 C 언어(C) 유형, 일반 Objective-C 객체에 대한 포인터, `NSArray *`, `NSImage *`, `NSString *`와 같은 특정 유형의 객체에 대한 포인터 또는 메서드가 속한 클래스에 대한 포인터(instancetype)일 수 있다. 기본 반환 유형은 일반 Objective-C 유형 `id`이다.
메서드 인수는 메서드 이름의 일부인 인수를 레이블하는 이름으로 시작하고, 그 뒤에 콜론이 오고, 괄호 안에 예상되는 인수 유형과 인수 이름이 온다. 레이블은 생략할 수 있다.
```objc
- (void)setRangeStart:(int)start end:(int)end;
- (void)importDocumentWithName:(NSString *)name
withSpecifiedPreferences:(Preferences *)prefs
beforePage:(int)insertPage;
```
인터페이스 정의의 파생물은 기존 클래스에 메서드를 추가할 수 있는 ''카테고리''이다.[22]
3. 2. 2. 구현(Implementation)
C++와 비슷하게 클래스의 선언과 구현은 헤더 파일과 소스 파일로 나뉜다. 헤더 파일의 확장자는 .h로 동일하나, 소스 파일의 확장자는 .c나 .cpp가 아닌 .m (C에 대응) 또는 .mm (C++에 대응)이다.[63] 확장자가 .m 또는 .mm으로 정해진 이유는 단지 .o와 .c가 C에 의해 사용되고 있었기 때문이다.[63]클래스 구현은 `@implementation`으로 시작하고 `@end`로 끝난다. 클래스 변수를 다시 적을 필요는 없고, 선언한 메서드의 구현만 하면 된다.
```objc
@implementation classname
+ (return_type)classMethod
{
// 구현
}
- (return_type)instanceMethod
{
// 구현
}
@end
```
Objective-C는 클래스의 인터페이스와 구현을 별도로 선언된 코드 블록에 넣도록 요구한다. 관례적으로 개발자는 인터페이스를 헤더 파일에, 구현을 코드 파일에 넣는다. 일반적으로 .h로 끝나는 헤더 파일은 C 헤더 파일과 유사하며, 일반적으로 .m으로 끝나는 구현(메서드) 파일은 C 코드 파일과 매우 유사할 수 있다. 이는 C++(C++)나 파이썬(Python)과 같은 다른 객체 지향 언어에서 사용되는 클래스 선언과 유사하다.
인터페이스 정의의 파생물은 기존 클래스에 메서드를 추가할 수 있는 ''카테고리''이다.[22] 인터페이스는 클래스 인터페이스만 선언하며, 메서드 자체는 선언하지 않는다. 실제 코드는 구현 파일에 작성된다. 구현(메서드) 파일은 일반적으로 파일 확장자
.m
을 가지며, 원래 "메시지"를 의미했다.[23]메서드는 인터페이스 선언을 사용하여 작성된다. Objective-C와 C 비교는 아래 표와 같다.
Objective-C | C |
---|---|
위 코드는 유사-인수 명명 구문을 허용한다.
```objc
- (void)changeColorToRed:(float)red green:(float)green blue:(float)blue {
//... 구현 ...
}
// 다음과 같이 호출됩니다.
[myColor changeColorToRed:5.0 green:2.0 blue:6.0];
```
메서드의 내부 표현은 Objective-C의 다른 구현 간에 다르다. 예를 들어 myColor가 Color 클래스이고, 인스턴스 메서드 `-changeColorToRed:green:blue:`가 내부적으로 `_i_Color_changeColorToRed_green_blue`로 표시될 수 있다. 여기서 `i`는 인스턴스 메서드를 나타내며, 클래스와 메서드 이름이 추가되고 콜론은 밑줄로 변경된다. 매개변수의 순서는 메서드 이름의 일부이므로, 진정한 명명된 매개변수와 같이 코딩 스타일이나 표현에 맞게 변경할 수 없다.
그러나 함수의 내부 이름은 거의 직접 사용되지 않는다. 일반적으로 메시지는 Objective-C 런타임 라이브러리에 정의된 함수 호출로 변환된다. 수신자(메시지를 보내는 객체)의 클래스가 런타임까지 알 필요가 없기 때문에 링크 시점에 어떤 메서드가 호출될지는 반드시 알려지지 않는다.
Objective-C의 클래스는 정의부와 구현부로 나뉘며, 일반적으로 정의부는 .h 파일, 구현부는 .m 파일에 기술한다. 후술할 카테고리에 의해 클래스 정의를 여러 파트로 분할할 수 있다.
메서드에는 클래스 메서드와 인스턴스 메서드가 있으며, 각각 접두사 `+` 및 `-`에 의해 구별된다. 클래스 메서드는 클래스 객체의 조작에, 인스턴스 메서드는 인스턴스 객체의 조작에 사용된다. 클래스 메서드는 특히 인스턴스 객체의 생성에도 많이 사용된다. 인스턴스 메서드는 인스턴스 객체에 메시지를 보낼 때 시작되며, 클래스 메서드는 클래스 객체에 메시지를 보낼 때 시작된다. 또한, 인스턴스 메서드와 클래스 메서드는 완전히 동일한 이름의 셀렉터를 지정하여 정의할 수 있다.
생성자는 별도로 존재하지 않는다. 관습적으로 새 객체의 생성은 `+alloc`으로, 초기화는 `-init`로 이루어지지만, 프로그래머가 자유롭게 다른 특수화된 메서드를 정의할 수 있으며, 초기화 중에 다른 초기화 메서드를 호출하는 경우도 있다. 반면 소멸자(파이널라이저)에 해당하는 것은 `-dealloc` 또는 가비지 컬렉션 사용 시의 `-finalize`로, 이들 메서드는 객체의 파괴 시에 반드시 호출된다.
self는 특수한 변수로, 메서드 실행 시에 자동으로 리시버가 대입된다. 재할당도 가능하며, `-init` 등에서 슈퍼 클래스의 구현으로 자신을 초기화하고, 올바른 값이 반환되었을 경우에만 계속 초기화를 수행하는 등에 이용된다.
3. 3. 프로토콜(Protocols)
NeXT는 오브젝티브-C에 다중 상속을 도입하기 위해 프로토콜을 추가했다. 이는 C++(C++)에서 추상적으로 다중 상속되는 기본 클래스 또는 자바 (프로그래밍 언어)나 C#에서 "인터페이스(interface)"를 구현하기 위한 패턴이다. 오브젝티브-C는 비공식 프로토콜(informal protocol)과 공식 프로토콜(formal protocol)을 통해 다중 상속과 유사한 기능을 제공한다.[64]- 비공식 프로토콜 (Informal Protocol): 클래스가 선택적으로 구현할 수 있는 메서드 목록이다. 언어 자체에 명시되지 않고 문서에 기술된다. 주로 선택적 메서드를 포함하며, 구현될 경우 클래스의 동작을 변경할 수 있다. 예를 들어, 텍스트 필드 클래스는 자동 완성 기능을 위한 선택적 메서드를 가진 비공식 프로토콜을 구현하는 위임을 가질 수 있다.
- 공식 프로토콜 (Formal Protocol): 자바, C#, 에이다 2005의 인터페이스와 유사하다. 클래스가 구현한다고 선언할 수 있는 메서드 목록이다. Objective-C 2.0 이전에는 프로토콜의 모든 메서드를 구현해야 했으나, 2.0부터는 선택적 메서드 표시가 가능해져 컴파일러가 구현을 강제하지 않는다.
공식 프로토콜은 구현을 제공하지 않으며, 프로토콜을 준수하는 클래스가 구현을 제공할 것을 보장한다. NeXT/Apple 라이브러리에서 프로토콜은 분산 객체 시스템에서 원격 객체의 기능을 나타내는 데 자주 사용된다.
프로토콜 정의 예시:```objc
@protocol NSLocking
- (void)lock;
- (void)unlock;
@end
```
위 코드는 잠금(lock)과 잠금 해제(unlock)라는 추상적인 개념을 나타낸다.
클래스 정의에서 프로토콜 구현 명시 예시:```objc
@interface NSLock : NSObject
// ...
@end
```
`NSLock`의 인스턴스는 `NSLocking` 프로토콜에 명시된 두 개의 인스턴스 메서드에 대한 구현을 제공한다.
3. 4. 카테고리 (Categories)
오브젝티브-C 설계 과정에서 주요 관심사 중 하나는 대규모 코드 베이스의 유지 관리성이었다. 구조적 프로그래밍 세계의 경험은 코드를 개선하는 주요 방법 중 하나가 코드를 더 작은 조각으로 나누는 것임을 보여주었다. Objective-C는 이러한 프로세스를 돕기 위해 Smalltalk 구현에서 ''카테고리''의 개념을 차용하고 확장했다.[25]카테고리는 클래스 정의를 그룹으로 분할하거나, 기존 클래스에 메서드를 추가하기 위한 언어 기능이다. 클래스 카테고리와 메서드 카테고리(프로토콜이라고도 함)를 그대로 가져왔다. 이것은 Smalltalk가 통합 개발 환경에서 클래스와 메서드의 표시를 정리하기 위해 사용하고 있는 개념이다.
클래스 구현을 관련 메서드 그룹별로 별도의 위치에 분할하여 기술하는 것을 가능하게 하기 위해 만들어졌다.
또한, 카테고리 내의 메서드는 런타임에 클래스에 추가된다. 따라서 카테고리를 사용하면 프로그래머가 해당 클래스를 다시 컴파일하거나 소스 코드에 접근할 필요 없이 기존 클래스 (오픈 클래스)에 메서드를 추가할 수 있다. 예를 들어, 시스템에 String 구현에 맞춤법 검사기가 포함되어 있지 않은 경우 String 소스 코드를 수정하지 않고도 추가할 수 있다.[25]
이 외에도, 카테고리에 선언한 메서드가 실행 시 카테고리가 로드된 타이밍에 클래스에 추가되는 성질을 응용하여, 소스 코드를 직접 수정할 수 없는 클래스에 대해 서브클래스를 정의하지 않고 메서드를 추가하는 용도나, Informal 프로토콜 정의 등에도 사용된다.
카테고리 내의 메서드는 프로그램이 실행될 때 클래스의 메서드와 구별할 수 없게 된다. 카테고리는 비공개 변수를 포함하여 클래스 내의 모든 인스턴스 변수에 대한 전체 액세스 권한을 갖는다.
카테고리가 클래스의 기존 메서드와 동일한 메서드 시그니처를 가진 메서드를 선언하는 경우 카테고리의 메서드가 채택된다. 따라서 카테고리는 클래스에 메서드를 추가할 뿐만 아니라 기존 메서드를 대체할 수도 있다. 이 기능을 사용하면 다른 클래스의 메서드를 다시 작성하여 버그를 수정하거나 프로그램 내에서 클래스의 동작을 전역적으로 변경할 수 있다. 두 개의 카테고리가 이름은 같지만 서로 다른 메서드 시그니처를 가진 메서드를 갖는 경우 어느 카테고리의 메서드가 채택되는지는 정의되지 않는다.
카테고리 메서드로 기존 메서드를 오버라이드하는 것도 가능하지만, 권장되지 않는다.
다른 언어들은 다양한 방식으로 이 기능을 추가하려고 시도했다. TOM은 Objective-C 시스템을 한 단계 더 발전시켜 변수도 추가할 수 있도록 했다. 다른 언어들은 프로토타입 기반 프로그래밍 솔루션을 대신 사용했는데, 가장 주목할 만한 것은 Self이다.
C# 및 Visual Basic (.NET) 언어는 확장 메서드 형태의 표면적으로 유사한 기능을 구현하지만, 클래스의 비공개 변수에 액세스할 수 없다.[26] 루비 및 기타 여러 동적 프로그래밍 언어는 이 기술을 "몽키 패치"라고 부릅니다.
Logtalk은 Objective-C 카테고리 기능을 포함하는 (일급 엔티티로서) 카테고리 개념을 구현한다(Logtalk 카테고리는 특히 새 클래스 또는 프로토타입을 정의할 때 세분화된 구성 단위로도 사용할 수 있습니다. 특히 Logtalk 카테고리는 임의의 수의 클래스 및 프로토타입에 의해 가상으로 가져올 수 있습니다).
3. 5. 포징 (Posing)
Objective-C는 한 클래스가 프로그램 내에서 다른 클래스를 완전히 대체하는 것을 허용한다. 대체되는 클래스는 대상 클래스 "대신하는(pose as)" 것으로 간주된다.클래스 포징은 Mac OS X v10.5에서 사용 중단되었으며, 64비트 런타임에서는 사용할 수 없다. 유사한 기능은 동일한 시그니처를 가진 다른 메서드의 구현을 교체하는 카테고리에서 메서드 스위즐링을 사용하여 구현할 수 있다.
포징을 여전히 지원하는 버전의 경우, 대상 클래스에 전송된 모든 메시지는 대신 포징 클래스에서 수신한다. 몇 가지 제한 사항이 있다.
- 클래스는 직접 또는 간접 상위 클래스 중 하나만 대신할 수 있다.
- 포징 클래스는 대상 클래스에 없는 새로운 인스턴스 변수를 정의해서는 안 된다 (메서드를 정의하거나 재정의할 수는 있음).
- 대상 클래스는 포징 전에 어떤 메시지도 수신하지 않았어야 한다.
포징은 카테고리와 마찬가지로 기존 클래스의 전역 확장을 허용한다. 포징은 카테고리에서는 사용할 수 없는 두 가지 기능을 허용한다.
예를 들어, 다음과 같이 하면 NSApplication에 대한 `setMainMenu`의 모든 호출을 가로챌 수 있다.
```objc
@interface CustomNSApplication : NSApplication
@end
@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu {
// 메뉴로 작업 수행
}
@end
class_poseAs ([CustomNSApplication class], [NSApplication class]);
3. 6. #import
C 언어에서 `#include
` 전처리 지시어는 항상 해당 지점에서 파일의 내용을 소스에 삽입한다. Objective-C에는 `#import
` 지시어가 있는데, 각 파일이 컴파일 단위당 한 번만 포함된다는 점을 제외하면 `#include
`와 동일하며, 이로 인해 include 가드가 필요하지 않다.4. Objective-C 2.0
2006년 세계 개발자 회의에서 애플은 Objective-C 2.0을 발표했다.[65] 이는 "현대적인 가비지 컬렉션, 문법 기능 향상[65], 런타임 성능 개선[66], 64비트 지원"을 포함하는 Objective-C 언어의 개정판이었다.[65] Mac OS X v10.5는 Objective-C 2.0 컴파일러를 포함했다.[31]
Objective-C 2.0의 주요 변경 사항은 다음과 같다.
- 가비지 컬렉션 도입: 세대별 보수적 가비지 컬렉션(GC)을 도입하여 메모리 관리를 자동화했다. GC 모드에서는 멀티 스레드 관련 성능이 향상되었다. 가비지 컬렉션은 OS X 10.11을 마지막으로 폐지되었다.
- 프로퍼티 도입: C# 등에 채용된 프로퍼티가 추가되어 세터/게터의 취급을 간소화했다. 점 표기법(dot notation)을 사용하여 `obj.propName`과 같이 접근할 수 있게 되었다.
- 빠른 열거(Fast Enumeration): foreach 문과 유사한 방식으로, 컬렉션 객체의 요소를 쉽게 순회할 수 있게 되었다.
- 프로토콜 강화: 구현 옵션의 프로토콜 정의가 늘었다.
- 클래스 확장(Class Extensions): 구현이 필수인 비공개 메서드를 (인터페이스적으로) 공개하지 않고 사용할 때 유용하다.
- 런타임 구조 변경: 클래스 posing이 폐지되고 메서드 교환 기능이 제공되었다.
4. 1. 가비지 컬렉션 (Garbage collection)
Objective-C 2.0은 선택적이며 보수적인 세대별 가비지 컬렉터를 제공했다. 하위 호환성 모드로 실행될 때, 런타임은 "retain" 및 "release"와 같은 참조 카운팅 연산을 무효 연산으로 전환했다. 가비지 컬렉션이 활성화되면 모든 객체는 가비지 컬렉션의 대상이 되었다. 일반 C 포인터는 "__strong"으로 한정하여 기본 쓰기 배리어 컴파일러 인터셉트를 트리거하고 가비지 컬렉션에 참여할 수 있었다.[34] "__weak"로 표시된 포인터가 객체(또는 더 간단하게 GC 메모리)가 수집될 때 0으로 설정되는 0 설정 약한 하위 시스템도 제공되었다. 가비지 컬렉터는 Objective-C 2.0의 iOS 구현에는 존재하지 않는다.[35] Objective-C의 가비지 컬렉션은 낮은 우선순위의 백그라운드 스레드에서 실행되며, 사용자 이벤트 시 중단될 수 있어, 사용자 경험을 응답적으로 유지하는 것을 목표로 했다.[36]가비지 컬렉션은 자동 참조 카운팅(ARC)을 선호하여 Mac OS X v10.8에서 더 이상 사용되지 않게 되었다.[37]
4. 2. 프로퍼티 (Properties)
Objective-C 2.0은 인스턴스 변수를 프로퍼티로 선언하는 새로운 구문을 도입했으며, 선택적으로 접근자 메서드 생성을 구성하는 속성을 제공한다. 프로퍼티는 일종의 public 인스턴스 변수로, 인스턴스 변수를 프로퍼티로 선언하면 외부 클래스가 해당 프로퍼티에 (읽기 전용 등 제한적으로) 접근할 수 있게 한다. 프로퍼티는 "readonly"로 선언할 수 있으며, `assign`, `copy` 또는 `retain`과 같은 저장 의미 체계를 제공할 수 있다. 기본적으로 프로퍼티는 `atomic`으로 간주되어 여러 스레드가 동시에 접근하는 것을 방지하는 잠금이 생성된다. 프로퍼티는 `nonatomic`으로 선언하여 이 잠금을 제거할 수 있다.[31]@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
- (id)initWithAge:(int)age;
@end
프로퍼티는 `@synthesize` 키워드를 사용하여 구현되며, 프로퍼티 선언에 따라 getter (읽기 전용이 아닌 경우 setter) 메서드를 생성한다. 또는 getter 및 setter 메서드를 명시적으로 구현하거나, `@dynamic` 키워드를 사용하여 접근자 메서드가 다른 방식으로 제공될 것임을 나타낼 수 있다. clang 3.1 이상을 사용하여 컴파일하는 경우, `@dynamic`으로 명시적으로 선언되지 않거나, `readonly`로 표시되거나, 사용자 구현 getter 및 setter가 완료된 모든 프로퍼티는 자동으로 암시적으로 `@synthesize` 된다.[31]
@implementation Person
@synthesize name;
- (id)initWithAge:(int)initAge {
self = [super init];
if (self) {
// NOTE: direct instance variable assignment, not property setter
age = initAge;
}
return self;
}
- (int)age {
return age;
}
@end
프로퍼티는 기존의 메시지 전달 구문, 점 표기법 또는 키-값 코딩에서 "valueForKey:"/"setValue:forKey:" 메서드를 통해 이름으로 액세스할 수 있다.[31]
Person *aPerson =
aPerson.name = @"Steve"; // NOTE: dot notation, uses synthesized setter,
// equivalent to [aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@), property name(% @) and "
"direct instance variable access(% @) ",
[aPerson name],
aPerson.name, [aPerson valueForKey:@"name"], aPerson -> name);
인스턴스 메서드 내에서 점 표기법을 사용하여 프로퍼티 접근자를 호출하려면 `self` 키워드를 사용해야 한다.[31]
- (void)introduceMyselfWithProperties:(BOOL)useGetter {
NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name));
// NOTE: getter vs. ivar access
}
클래스 또는 프로토콜의 프로퍼티는 동적으로 검사할 수 있다.[31]
int i;
int propertyCount = 0;
objc_property_t *propertyList =
class_copyPropertyList([aPerson class], &propertyCount);
for (i = 0; i < propertyCount; i++) {
objc_property_t *thisProperty = propertyList + i;
const char *propertyName = property_getName(*thisProperty);
NSLog(@"Person has a property: '%s'", propertyName);
}
4. 3. 빠른 열거 (Fast enumeration)
오브젝티브-C 2.0에서는 객체를 순회하기 위해 `NSEnumerator` 객체 또는 인덱스를 사용하는 대신, 빠른 열거 구문을 제공한다.[29] [30] [31] 오브젝티브-C 2.0에서 다음 루프는 기능적으로 동일하지만, 다른 성능 특성을 가진다.```objc
// NSEnumerator 사용
NSEnumerator *enumerator = [thePeople objectEnumerator];
Person *p;
while ((p = [enumerator nextObject]) != nil) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
```
```objc
// 인덱스 사용
for (int i = 0; i < [thePeople count]; i++) {
Person *p = [thePeople objectAtIndex:i];
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
```
```objc
// 빠른 열거 사용
for (Person *p in thePeople) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
```
빠른 열거는 객체를 열거하기 위한 메서드 호출이 `NSFastEnumeration` 프로토콜을 사용하는 포인터 연산으로 대체되기 때문에 표준 열거보다 더 효율적인 코드를 생성한다.
4. 4. 클래스 확장 (Class extensions)
클래스 익스텐션은 카테고리 이름이 없는 카테고리 선언과 동일한 구문을 가지며, 여기에 선언된 메서드와 프로퍼티는 메인 클래스에 직접 추가된다. 이는 주로 공개 헤더에 메서드를 공표하지 않고 클래스에 메서드를 추가하기 위한 카테고리의 대안으로 사용되며, 클래스 익스텐션의 경우 컴파일러가 비공개로 선언된 모든 메서드가 실제로 구현되었는지 검사한다는 장점이 있다.[41]5. 현대 Objective-C
현대 Objective-C는 코드 가독성과 효율성을 높이는 여러 기능을 도입하여 개발자 편의를 도모하고 있다. 주요 기능은 다음과 같다.
- 자동 참조 카운팅 (ARC): 컴파일 시점에 자동으로 메모리 관리 코드를 삽입하여 개발자가 직접 참조 횟수를 관리할 필요가 없게 한다. LLVM 3.0 (Xcode 4.2)부터 도입되었다.[44][45]
- 리터럴: 배열, 딕셔너리, 숫자 객체를 간편하게 생성하는 `@[]`, `@{}`, `@()`와 같은 축약형 문법을 제공한다. 애플 LLVM 컴파일러 4.0 (Xcode 4.4)부터 지원된다.[46]
- 서브스크립팅: 배열(`NSArray`)과 딕셔너리(`NSDictionary`) 객체에 대괄호(`[]`)를 사용하여 접근할 수 있게 한다. 애플 LLVM 컴파일러 4.0 이상에서 지원된다.[46][48]
5. 1. 자동 참조 카운팅 (Automatic Reference Counting, ARC)
자동 참조 카운팅(ARC)은 프로그래머가 `retain` 및 `release`를 사용하여 수동으로 참조 횟수를 관리할 필요가 없도록 하는 컴파일 타임 기능이다.[44] 가비지 컬렉션과는 달리, 런타임에 발생하는 것이 아니며, 참조 횟수를 관리하는 별도의 프로세스에 대한 오버헤드도 없다.ARC는 LLVM 3.0에 도입되었다. 이는 Xcode 4.2(2011) 또는 애플 LLVM 컴파일러 3.0으로 번역된다.[45]
ARC는 내부적으로 `retain`/`release`/`autorelease`와 유사한 메커니즘으로 작동하지만, 컴파일 시 메서드의 명명 규칙 등을 보고 자동으로 `retain`/`release`에 해당하는 코드를 삽입하는 방식이다. 이 때문에 ARC에서는 명시적으로 `retain`/`release`를 사용하는 것이 불가능하다. 관리 관련 코드가 줄어들고, `autorelease` 관리의 실행 효율이 향상되어, 기존 방식의 프로그램을 ARC로 전환하는 것만으로도 성능을 어느 정도 높일 수 있다.
5. 2. 리터럴 (Literals)
NeXT와 애플의 오브젝티브-C 런타임은 오랫동안 문자열을 생성하는 단축 형식을 포함해왔다. 바로 `@""`와 같은 리터럴 구문을 사용하는 것이다.[46] 애플 LLVM 컴파일러 4.0(Xcode 4.4) 이상을 사용하면 메서드 대신 배열, 딕셔너리 및 숫자(`NSArray`, `NSDictionary`, `NSNumber` 클래스)도 리터럴 구문을 사용하여 생성할 수 있다.[46]리터럴을 사용하지 않는 예시와 리터럴을 사용하는 예시는 다음과 같다.
'''리터럴이 없는 예'''
- `NSArray *myArray = [NSArray arrayWithObjects:object1,object2,object3,nil];`
- `NSDictionary *myDictionary1 = [NSDictionary dictionaryWithObject:someObject forKey:@"key"];`
- `NSDictionary *myDictionary2 = [NSDictionary dictionaryWithObjectsAndKeys:object1, key1, object2, key2, nil];`
- `NSNumber *myNumber = [NSNumber numberWithInt:myInt];`
- `NSNumber *mySumNumber= [NSNumber numberWithInt:(2 + 3)];`
- `NSNumber *myBoolNumber = [NSNumber numberWithBool:YES];`
'''리터럴이 있는 예'''
- `NSArray *myArray = @[ object1, object2, object3 ];`
- `NSDictionary *myDictionary1 = @{ @"key" : someObject };`
- `NSDictionary *myDictionary2 = @{ key1: object1, key2: object2 };`
- `NSNumber *myNumber = @(myInt);`
- `NSNumber *mySumNumber = @(2+3);`
- `NSNumber *myBoolNumber = @YES;`
- `NSNumber *myIntegerNumber = @8;`
5. 3. 서브스크립팅 (Subscripting)
애플 LLVM 컴파일러 4.0 이상을 사용하는 경우, 배열과 사전(`NSArray` 및 `NSDictionary` 클래스)은 서브스크립팅을 사용하여 조작할 수 있다.[46] 서브스크립팅은 인덱스(배열) 또는 키(사전)에서 값을 가져오는 데 사용될 수 있으며, 가변 객체의 경우 인덱스 또는 키에 객체를 설정하는 데에도 사용될 수 있다. 코드에서 서브스크립팅은 대괄호 `[ ]`를 사용하여 표시된다.[48]서브스크립팅을 사용하지 않는 경우의 예시는 다음과 같다.
```objc
id object1 = [someArray objectAtIndex:0];
id object2 = [someDictionary objectForKey:@"key"];
[someMutableArray replaceObjectAtIndex:0 withObject:object3];
[someMutableDictionary setObject:object4 forKey:@"key"];
```
서브스크립팅을 사용하는 경우의 예시는 다음과 같다.
```objc
id object1 = someArray[0];
id object2 = someDictionary[@"key"];
someMutableArray[0] = object3;
someMutableDictionary[@"key"] = object4;
6. 언어 변종
Objective-C에는 다음과 같은 여러 변종이 존재한다.
- Objective-C++: GNU 컴파일러 모음(GCC)과 클랭 프론트엔드가 수용하는 언어 변종이다. C++와 Objective-C 문법을 함께 사용하여 소스 파일을 컴파일할 수 있으며, C++에 Objective-C가 C에 추가하는 확장 기능을 포함한다.[27] 주로 C++ 라이브러리를 Objective-C에서 접근하기 위한 래퍼를 작성하는 데 사용되며, 애플(Apple Inc.)의 WebKit(KHTML 기반) 등이 실제 사례이다.
- mulle-objc: Objective-C의 또 다른 재구현이다. GCC 또는 Clang/LLVM 컴파일러를 백엔드로 지원하며, Linux, FreeBSD 및 Windows를 지원한다.
- Portable Object Compiler: Stepstone의 원본 구현에 몇 가지 확장을 추가한 자유 오픈 소스 Objective-C 구현체이다.[50] Objective-C용 스몰토크와 유사한 블록을 포함한다.
- GEOS Objective-C: PC GEOS 시스템에서 사용된 프로그래밍 언어로, '''goc'''으로도 알려져 있다.[51] 이름은 유사하지만, 전체적인 개념과 @ 기호로 시작하는 키워드를 사용한다는 점만 Objective-C와 유사하다.
6. 1. Objective-C++
Objective-C++는 GNU 컴파일러 모음(GCC)과 클랭 프론트엔드가 수용하는 언어 변종이다. C++와 Objective-C 문법을 함께 사용하여 소스 파일을 컴파일할 수 있다. Objective-C++는 C++에 Objective-C가 C에 추가하는 확장 기능을 포함한다.[27]Objective-C와 C++가 혼재된 형태이다. 양쪽은 C로부터 확장된 부분이 거의 간섭하지 않기 때문에, 서로를 단순한 포인터 값으로 간주하여 표기를 혼재할 수 있다. 따라서 클래스 시스템 호환성은 없으며, 단순한 Objective-C 및 C++가 된다. 확장자는 .mm이다.
함수나 Objective-C 메서드 내부에서는 Objective-C와 C++ 양쪽 기능을 임의로 조합하여 사용할 수 있다. 예를 들어, Objective-C 객체의 수명을 관리하는 스마트 포인터를 C++ 기능을 이용하여 생성할 수 있다. 반면, 클래스 계층 구조는 Objective-C와 C++에서 완전히 분리되어 있으며, 한쪽이 다른 쪽을 상속하는 것은 불가능하다. 또한, 전통적인 Objective-C 예외 처리와 C++의 예외 처리는 호환성이 없어, 프로그래머가 양쪽을 일일이 포착・변환하지 않으면 메모리 누수나 크래시로 이어진다.[27]
주로 C++ 라이브러리를 Objective-C에서 접근하기 위한 래퍼를 작성하는 데 사용되며, 실제 사례로 애플(Apple Inc.)의 WebKit(KHTML 기반) 등이 있다. 컴파일 속도가 매우 느려져 적극적으로 사용되는 경우는 적다.
6. 2. mulle-objc
mulle-objc 프로젝트는 오브젝티브-C의 또 다른 재구현이다. GCC 또는 Clang/LLVM 컴파일러를 백엔드로 지원한다. 구문, 의미 체계 및 ABI 호환성 측면에서 다른 런타임과 다르다. Linux, FreeBSD 및 Windows를 지원한다.6. 3. Portable Object Compiler
GCC/NeXT/애플 구현 외에도, Stepstone의 원본 구현에 몇 가지 확장을 추가한 또 다른 자유 오픈 소스 Objective-C 구현체인 Portable Object Compiler (POC)도 존재한다.[50] Portable Object Compiler에서 구현된 확장 세트는 GCC/NeXT/Apple 구현과 다르다. 특히, OpenStep 및 그 파생물과 관련 제품에서 광범위하게 사용되는 프로토콜과 카테고리가 없는 반면, Objective-C용 스몰토크와 유사한 블록을 포함한다. 전반적으로 POC는 Brad Cox의 1991년 저서에 대략적으로 부합하는 언어 진화의 초기, NeXT 이전 단계를 나타낸다.6. 4. GEOS Objective-C
PC GEOS 시스템은 '''GEOS Objective-C''' 또는 '''goc'''으로 알려진 프로그래밍 언어를 사용했다.[51] 이름의 유사성에도 불구하고 두 언어는 전체적인 개념과 @ 기호로 시작하는 키워드를 사용한다는 점만 유사하다.7. 라이브러리 사용
오늘날 Objective-C는 코코아, GNUstep, 또는 ObjFW와 같은 표준 객체의 고정된 라이브러리(종종 "키트" 또는 "프레임워크"로 알려짐)와 함께 사용되는 경우가 많다. 이러한 라이브러리는 종종 운영 체제와 함께 제공된다. GNUstep 라이브러리는 리눅스 기반 배포판과 함께 제공되며, 코코아는 macOS와 함께 제공된다. 프로그래머는 기존 기본 클래스(NSObject - OFObject)에서 함수를 상속받을 필요가 없다. Objective-C는 기존 함수를 상속받지 않는 새로운 루트 클래스의 선언을 허용한다. 원래 Objective-C 기반 프로그래밍 환경은 일반적으로 거의 모든 다른 클래스가 상속받는 Object 클래스를 기본 클래스로 제공했다. OpenStep이 도입되면서 NeXT는 Object보다 추가 기능을 제공하는 NSObject라는 새로운 기본 클래스를 만들었다(예: 원시 포인터 대신 객체 참조 및 참조 카운팅 사용에 대한 강조). 코코아의 거의 모든 클래스는 NSObject를 상속받는다.
이러한 이름 변경은 OpenStep API 내에서 클래스의 새로운 기본 동작을 차별화하는 데 기여했을 뿐만 아니라, Object(NeXTSTEP(그리고 대략적으로 다른 Objective-C 클래스 라이브러리)에서 사용된 원래 기본 클래스)를 사용한 코드가 (일부 제약 조건이 있지만) NSObject를 사용한 코드와 동일한 런타임에서 공존할 수 있도록 했다. 두 글자 접두사의 도입은 또한 Objective-C가 부족한 단순화된 형태의 네임스페이스가 되었다. 접두사를 사용하여 비공식 패키징 식별자를 만드는 것은 Objective-C 커뮤니티에서 비공식적인 코딩 표준이 되었으며 오늘날까지 이어지고 있다.
최근에는 CocoaPods와 같은 패키지 관리자가 등장하여 패키지 관리자이자 패키지 저장소를 목표로 한다. 지난 몇 년 동안 작성된 많은 오픈 소스 Objective-C 코드는 이제 CocoaPods를 사용하여 설치할 수 있다.
8. 언어 분석
Objective-C 구현은 C로 작성된 얇은 런타임 시스템을 사용하여 애플리케이션의 크기를 거의 늘리지 않는다.[58] 이를 통해 Objective-C는 방대한 기존 C 코드, 라이브러리, 도구 등을 활용할 수 있으며, 기존 C 라이브러리는 객체 지향(OO) 스타일 인터페이스를 제공하기 위해 Objective-C 래퍼로 래핑될 수 있다.[58]
Objective-C는 네임스페이스에 대한 언어 지원이 없다. 대신 프로그래머는 클래스 이름에 접두사를 추가해야 한다. 2007년 현재, Cocoa 프로그래밍 환경의 모든 macOS 클래스 및 함수는 "NS"로 시작하는데(예: NSObject, NSButton), 이는 NeXTSTEP에서 유래했다.[58]
Objective-C는 C의 엄격한 상위 집합이므로 C 기본 유형을 일급 객체로 취급하지 않는다.[58] C++와 달리 연산자 오버로딩을 지원하지 않으며, 객체가 하나의 클래스에서만 직접 상속받을 수 있도록 허용한다(다중 상속 금지). 그러나 대부분의 경우, 카테고리와 프로토콜은 동일한 결과를 달성하는 대체 방법으로 사용될 수 있다.[58]
Objective-C는 동적 런타임 타이핑을 사용하고 모든 메서드 호출이 함수 호출(또는 경우에 따라 시스템 호출)이기 때문에 인라인화, 상수 전파, 절차 간 최적화 및 집계의 스칼라 대체와 같은 많은 일반적인 성능 최적화를 적용할 수 없다.[58]
Objective-C는 C를 확장하여 객체 지향을 가능하게 했다기보다는, C로 작성된 객체 지향 시스템을 제어하기 쉽도록 매크로적인 확장을 가한 언어이다. C와는 다른 Objective-C 특유의 부분은 `@`로 시작하는 '''컴파일러 지시자'''로 명시되며, 객체의 메서드 호출은 `[` `]`로 둘러싸인 '''메시지 표현식'''으로 수행된다.[58] 객체 시스템이 완전히 동적이라는 점이 최대 특징으로, 실행 시 클래스 확장, 객체 범용형 id의 도입에 의해 타입에 구애받지 않는 동적 배열·사전 등, 인터프리터에 가까운 기술력을 갖추고 있다.[58]
함수(메서드)의 정의와 호출 방법이 독특하기 때문에, Objective-C의 코드는 언뜻 C++ 이상으로 C와는 동떨어진 독특한 기술이 된다. 그러나 언어 사양은 C의 완전 상위 호환이며, if, for, while 등의 제어문이나 int 등의 스칼라형, 함수 표기법, 선언·대입과 같은 기본적인 문법은 C에 준한다.[58]
클래스 | 단일 상속 + 인터페이스 다중 상속(프로토콜). 보통은 루트 클래스에서 상속. |
---|---|
객체 시스템 | 동적 바인딩, 메타클래스를 가짐. |
타입 | 동적 타입 + 외형상의 정적 타입의 하이브리드. |
실행 속도 | 코드는 C와 동등한 네이티브 컴파일, 메서드 호출은 동적 디스패치를 수행하므로 약간 지연된다. 평균적으로 C/C++보다 다소 느리고, 중간 코드형 언어(Java 등)보다 수 배 정도 빠르다고 한다. 다만, 중요한 부분은 언제든지 C로 다시 작성할 수 있으므로, 실행 속도가 문제가 되는 경우는 거의 없다. |
기타 | 객체는 포인터 호환, C의 스칼라형은 객체가 아님. |
참조
[1]
웹사이트
Runtime Versions and Platforms
https://developer.ap[...]
2017-12-24
[2]
웹사이트
Chris Lattner's Homepage
http://nondot.org/sa[...]
Chris Lattner
2014-06-03
[3]
웹사이트
A Brief History of Mac OS X
http://osxbook.com/b[...]
Mac OS X Internals
2012-06-11
[4]
웹사이트
App Frameworks
https://developer.ap[...]
Apple
2019-02-13
[5]
간행물
iPhone Coding Language Now World's Third Most Popular
https://www.wired.co[...]
2013-05-20
[6]
서적
Cocoa: Volume 5 of Developer Reference Apple Developer Series
https://books.google[...]
John Wiley and Sons
2016-07-22
[7]
서적
Masterminds of Programming
https://books.google[...]
O'Reilly Media, Inc.
2016-07-22
[8]
학술
The object oriented pre-compiler: programming Smalltalk-80 methods in C language
https://portal.acm.o[...]
Association for Computing Machinery
2011-02-17
[9]
웹사이트
Common Lisp and Readline
https://github.com/J[...]
2014-09-15
[10]
웹사이트
GNUstep: Introduction
http://www.gnustep.o[...]
GNUstep developers/GNU Project
2012-07-29
[11]
웹사이트
Kresten Krab Thorup {{!}} LinkedIn
https://www.linkedin[...]
2016-06-23
[12]
웹사이트
Write Objective-C Code
https://developer.ap[...]
apple.com
2013-12-22
[13]
웹사이트
Objective-C Boot Camp
https://www.informit[...]
2018-02-11
[14]
웹사이트
Examining Objective-C
http://www.drdobbs.c[...]
2014-09-04
[15]
서적
Pro Objective-C
https://books.google[...]
Apress
2017-12-24
[16]
웹사이트
Tags for Objective-C Headers
https://web.mit.edu/[...]
2018-02-11
[17]
웹사이트
AppScan Source 8.7 now available
https://www-01.ibm.c[...]
2018-02-11
[18]
웹사이트
Dynamic Method Resolution
https://developer.ap[...]
2014-11-25
[19]
웹사이트
Avoiding Messaging Errors
https://developer.ap[...]
2009-10-19
[20]
웹사이트
objc_msgSend - Objective-C Runtime
https://developer.ap[...]
2020-02-10
[21]
웹사이트
Messaging with the GNU Objective-C runtime
https://gcc.gnu.org/[...]
2020-02-10
[22]
웹사이트
Category
https://developer.ap[...]
[23]
서적
Learn Objective-C on the Mac
Apress
2012-06-27
[24]
웹사이트
Objective-C Runtime Programming Guide
https://developer.ap[...]
Apple Inc.
2013-10-21
[25]
웹사이트
ACM SIGGRAPH 1983 Issue 8 - Smalltalk
http://video.google.[...]
2008-10-07
[26]
웹사이트
Extension Methods (C# Programming Guide)
https://msdn.microso[...]
Microsoft
2011-07-10
[27]
웹사이트
Using C++ With Objective-C
https://developer.ap[...]
2010-02-10
[28]
웹사이트
Clang Language Extensions — Clang 3.5 documentation
https://clang.llvm.o[...]
Clang.llvm.org
2014-04-16
[29]
웹사이트
Objective-C 2.0: more clues
http://lists.apple.c[...]
Lists.apple.com
2010-05-30
[30]
웹사이트
Re: Objective-C 2.0
http://lists.apple.c[...]
Lists.apple.com
2010-05-30
[31]
웹사이트
GCC 4.6 Release Series — Changes, New Features, and Fixes : GNU Project : Free Software Foundation
https://gcc.gnu.org/[...]
2017-12-24
[32]
웹사이트
ObjC2 FAQ
http://wiki.gnustep.[...]
2020-01-06
[33]
웹사이트
Source Browser: objc4, 756.2
https://opensource.a[...]
2020-01-06
[34]
Webarchive
Garbage Collection Programming Guide: Garbage Collection API
https://developer.ap[...]
2012-06-09
[35]
웹사이트
Garbage Collection Programming Guide: Introduction to Garbage Collection
https://developer.ap[...]
Apple Inc.
2011-12-23
[36]
웹사이트
Leopard Technology Series for Developers: Objective-C 2.0 Overview
https://developer.ap[...]
Apple Inc.
2010-05-30
[37]
웹사이트
Transitioning to ARC Release Notes
https://developer.ap[...]
Apple Inc.
2012-08-26
[38]
웹사이트
Friday Q&A 2013-09-27: ARM64 and You
https://www.mikeash.[...]
mikeash.com
2014-04-27
[39]
웹사이트
'Hamster Emporium: [objc explain]: Non-pointer isa'
http://www.sealiesof[...]
Sealiesoftware.com
2014-04-27
[40]
웹사이트
Fast Enumeration
https://developer.ap[...]
apple.com
2009-12-31
[41]
웹사이트
GCC 4.6 Release Series – Changes, New Features, and Fixes
https://gcc.gnu.org/[...]
2013-11-27
[42]
웹사이트
Blocks Programming Topics – Mac Developer Library
https://developer.ap[...]
Apple Inc.
2012-11-28
[43]
웹사이트
Objective-C Automatic Reference Counting (ARC) — Clang 11 documentation
https://clang.llvm.o[...]
2020-02-20
[44]
웹사이트
Transitioning to ARC
https://developer.ap[...]
Apple Inc.
2012-10-08
[45]
웹사이트
LLVM 3.0 Release Notes
https://releases.llv[...]
[46]
웹사이트
Programming with Objective-C: Values and Collections
https://developer.ap[...]
Apple Inc.
2012-10-08
[47]
웹사이트
Clang 3.1 Release Notes
https://releases.llv[...]
[48]
웹사이트
Objective-C Literals — Clang 3.5 documentation
https://clang.llvm.o[...]
Clang.llvm.org
2014-04-16
[49]
간행물
Rhapsody Developer's Guide
AP Professional
[50]
웹사이트
Portable Object Compiler
http://users.pandora[...]
Users.pandora.be
2010-05-30
[51]
웹사이트
Breadbox Computer Company LLC homepage
http://www.breadbox.[...]
2010-12-08
[52]
웹사이트
gcc/libobjc
https://github.com/g[...]
gcc-mirror
2020-01-06
[53]
웹사이트
GNU Objective-C runtime API
https://gcc.gnu.org/[...]
2020-01-06
[54]
웹사이트
WinObjC on GitHub
https://github.com/M[...]
2018-02-13
[55]
웹사이트
GNUStep Installer
http://www.gnustep.o[...]
2018-02-14
[56]
웹사이트
Mac OS X Leopard – Xcode 3.0
https://www.apple.co[...]
apple.com
2006-08-22
[57]
웹사이트
Transitioning to ARC Release Notes
https://developer.ap[...]
Developer.apple.com
2014-04-16
[58]
웹사이트
世界のOSたち - 1990年代にコンピューターの未来を生み出した「NeXTSTEP」
https://news.mynavi.[...]
2023-11-13
[59]
웹사이트
Why Objective-C?
https://developer.ap[...]
2018-04-06
[60]
문서
[61]
웹사이트
'Xcode Release Notes {{!}} Xcode 8.3'
https://developer.ap[...]
2021-07-07
[62]
웹인용
Runtime Versions and Platforms
https://developer.ap[...]
2017-12-24
[63]
문서
[64]
서적
objective - C: 맥과 아이폰 애플리케이션 프로그래밍
한빛미디어(주)
2009-07-23
[65]
웹인용
Objective-C 2.0: more clues
http://lists.apple.c[...]
Lists.apple.com
2010-05-30
[66]
웹인용
Re: Objective-C 2.0
http://lists.apple.c[...]
Lists.apple.com
2010-05-30
관련 사건 타임라인
( 최근 20개의 뉴스만 표기 됩니다. )
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com