Objective-C

(♥ 0)



TIOBE 선정 올해의 프로그래밍 언어 / Objective-C
[펼치기 / 접기]
2010년
Python
2011년
Objective-C
2012년
Objective-C
2011년
Objective-C
2012년
Objective-C
2013년
Transact-SQL

[각주]

파일:12_objectivec.png
1. 개요
2. 역사
3. 특징
3.1. C의 확장
3.2. C++와의 비교
3.3. 문법
4. 여담
5. 위기
6. Cocoa 기반 언어
7. 관련 문서



1. 개요[편집]


// First program example
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSLog (@"Hello, World!");
    [pool drain];

    return 0;
}

C 언어에서 파생된 객체 지향 프로그래밍 언어. 오브젝트시(Object-C)라고 아는 사람이 많은데, '오브젝티브시'다. 국내 한정으로 보통 줄여서 옵씨, 오브젝씨라고 부르며, 이 문서도 해당 항목으로 들어올 수 있다.


2. 역사[편집]


1983년에 브래드 콕스와 톰 러브가 '스몰토크(Smalltalk)의 문법을 C에서 사용할 수 없을까?'라는 생각을 하다가 만들었다. 당시 애플에서 쫓겨나 넥스트 사를 차린 스티브 잡스의 눈에 띄어 Swift가 등장하기 전까지 애플의 표준 프로그래밍 언어로 사용되어 왔다. 넥스트가 아예 이 언어의 모든 권리를 구매해버렸고, 이건 고스란히 애플에게 넘어간 것. 지금도 Objective-C 언어의 표준화와 스펙 관리를 책임지는 주체가 애플이다.[1]


3. 특징[편집]



3.1. C의 확장[편집]


ANSI C언어에 무형성(untyped) 순수 객체 지향 언어인 스몰토크 형식의 객체 지향 패러다임을 확장 형태로 얹은 언어로[2], 실제로는 C언어라고 봐도 무방하다.[3] 그러나, C의 기본 자료형 및 표준 라이브러리에서 제공하는 것의 상당수를 Objective-C의 객체나 코코아 등에서 보다 손쉽게 사용할 수 있는 형태로 대체하고 있기 때문에, 실제 코드에 순수 C 부분은 많이 보이지 않는 편이다. 즉, 모든 C 코드가 다 문제 없이 작동하긴 하지만[4], C의 확장이라기보다 C에 Objective-C라는 새로운 언어를 덮어씌운 것에 가깝다.

C언어 표준 함수들을 제공하는 런타임에 더하여 Objective-C의 객체 지향 개념 추가를 위한 별도의 런타임이 필요하다. 하지만 그렇다고 JVM같은 가상 머신 위에서 동작하는 것은 아니고[5], 그저 객체간의 통신('메시징'이라고 부른다.)을 지원하는 초소형의 라이브러리를 링크하는 것이다.[6]


3.2. C++와의 비교[편집]


C의 확장이면서 여러가지 기능을 추가했다는 측면에서 C++와 자주 비교되는 경우가 많은데, 사실 두 언어는 발전의 방향이 다르다. C++는 Objective-C에 비하면 훨씬 육중한 언어로, 지원하는 기능도 많다. 실행 시간에 거의 모든 것을 수행하도록 설계된 Objective-C와는 달리 C++은 성능을 위해 대부분을 컴파일 시간에 처리하도록 되어있어 실행 시간의 스루풋 역시 C++ 쪽이 월등하다. 다만 그런 만큼 배우기도 힘들고, 배워서 그 모든 기능을 제대로 사용하기는 훨씬 더 힘들다.[7] 주요 컴파일러[8]가 C++17 표준 까지의 기능을 대부분 구현한 상태이긴 하지만, 새로운 기능이 워낙 많다 보니 컴파일러마다 아직 구현하지 못한 부분이 존재하는 것이 사실이다.[9] Objective-C는 거기에 비하면 훨씬 단순한 언어이고 애플 기기에서의 사용만을 고려해서 대상 기기의 폭이 무척 좁기 때문에 그런 경우는 거의 없다고 볼 수 있다. 또한, 비록 C++가 C에서 파생됐다고 해도, 이미 C라고 부르기엔 너무 진화해버린 언어[10]인 데 반해, Objective-C는 그냥 C 언어 위에 객체 지향 등의 확장을 추가한 수준이다. 즉, Objective-C는 곧 C라고 할 수 있다.

Objective-C의 내부로 조금 더 깊게 들어가자면, Objective-C의 모든 객체는 사실 C의 구조체(struct)로 이루어지고, 객체의 메서드는 해당 메서드 구현체(==함수)로의 함수 포인터를 클래스 객체[11]의 구조체 안에 리스트 형태로 들고 있다. 객체의 메서드를 호출하면 런타임의 objc_msgSend라는 함수를 통해 정확한 메서드 구현체를 찾아 호출한 후 결과를 돌려주는 형식이다.[12] 때문에 objc_msgSend 함수는 극도로 짧고 빠른 동작이 보장될 필요가 있어서 어셈블리 레벨에서 사람의 손으로 직접 작성됐다. 인터넷에서 만날 수 있는 몇몇 구루들이 분석한 바에 따르면, 최악의 상황에서도 대략 열몇 번의 CPU 사이클이면 정확하게 대상 메서드를 찾아온다고 한다.[13] 물론, 설계자들도 이 방식이 매우 느리다는 것을 알고 있었고, 그것 때문에 메서드 캐싱 기능[14]을 초창기부터 지원했다. 뭐, 그렇다고 해도 이 속도 문제 때문에 OS X을 겨냥하고 만들어진 프로그램도 퍼포먼스가 중요한 경우[15]에는 Objective-C보다는 C++로 작성하는 경우가 있다.[16]

애플은 저 런타임의 소스 코드를 오픈 소스로 공개했다. 따라서, 런타임과 Objective-C 지원 컴파일러만 있다면 OS X이 아닌 다른 플랫폼에서도 Objective-C를 사용할 수 있다.[17] 그래서 만들어진 것이 GNU그누스텝(GNUSTEP). 사실상 Objective-C를 맥 전용으로 강제하던 코코아 프레임워크를 자체적으로 다시 작성해 다른 플랫폼에서 사용이 가능하도록 했다.[18] 이것 말고도, 개인이 코코아 프레임워크를 처음부터 다시 작성하는 프로젝트를 진행 중이기도 하다.


3.3. 문법[편집]


Objective-C의 문법은 프로그래머마다 호불호가 크게 갈리는 편인데, 메소드 매개변수마다 어떤 용도인지 이름을 붙여주고 단순 블록만이 아닌 여러 가지 기호를 이용하여 구분하는데다가, 저런 '독특한' 문법이 해당 언어의 직계 선조인 순수 C와 명료하게 구분이 되는 편이기 때문에 읽기 쉬운 문법이라며 찬양하는 사람도 있는 반면, C와 100% 호환이 되지는 않지만 문법을 거의 다 C 스타일로 녹여낸 C++/Java/C\# 등의 대부분의 메이저 언어들과는 다른 길을 걷고 있기에 눈에 거슬린다며 비판하는 사람들도 많다.

아이러니하게도, Objective-C 찬양론자들은 Objective-C 의 가장 강력한 부분을 바로 저 이상한 문법에서 찾는다. 특히 메소드 호출 시 각각의 인자에 레이블을 붙여 이용하는 부분이 예시로 많이 등장하는데, 여러개의 인자를 받는 함수의 경우, 일반적인 C 계열 언어에서는 각각 인자가 어떤 역할을 하는지 함수명만 봐서는 알 수가 없기 때문에[19] 각각 인자의 위치와 순서를 따로 외우든가 아니면 코멘트를 써줘야 한다. 그러나 Objective-C 에서는 메소드명 자체가 저런 코멘트의 역할을 대신할 수 있다. 예를들어, (x, y) 좌표와 Width, Height 를 받아서 사각형을 그리는 메소드의 경우 Objective-C 에서는 drawSquarePosX:PosY:Width:Height: 같은 함수명을 사용할 수 있고, 실제 사용시에는
[self drawSquarePosX:130 PosY:70 Width:100 Height:150];
처럼 되기 때문에, 메시징하는 줄만 보고서도 그게 어떤 명령인지 대략적인 파악이 가능하다. 또한, 저 레이블 자체가 메소드명에 포함되기 때문에 Width 와 Height 대신 또다른 (x, y) 좌표를 받아서 사각형을 그릴 경우에도 네이밍 컨플릭트 없이 drawSquarePosX:PosY:PosX:PosY: 등과 같은 메소드를 정의할 수 있다. 물론, 이런 방식은 메소드명 자체가 좀 더 길어지는 부작용을 갖고있지만, Objective-C 의 용도상 Xcode가 아닌 일반 에디터를 사용해서 코딩하는 경우가 별로 없기 때문에 큰 문제로 생각되는 경우는 별로 없는 듯.


4. 여담[편집]


앱 스토어가 선풍적인 인기를 끌게 되면서 Objective-C를 배워서 앱을 출시하려는 일반인들이 많아졌으나, Objective-C가 생각처럼 배우기 쉬운 언어는 아니기 때문에[20], 중도하차하는 사람들이 많은 편이다. 사실 C 언어와 객체 지향 프로그래밍, GUI 프로그래밍에 대한 경험이 없다면, 꽤 고전할 가능성이 높다.

초창기 컴파일러를 만들 때, 넥스트에서 GCC 소스를 몰래 가져다가 자신들만의 Objective-C 컴파일러를 만들었었다. 그러다가 GNU에게 딱 걸려서, 결국 넥스트가 GCC를 기반으로 구현한 Objective-C 컴파일러와 기타 추가 기능을 다시 GCC에게 돌려주는 형태로 합의를 봤다고 한다. 이후 애플은 LLVM이라는 새로운 개념의 컴파일러 프로젝트를 통째로 인수했다.[21] 대학원 프로젝트로 시작된 것인데, 이 프로젝트를 처음 시작한 사람(크리스 래트너; Chris Lattner(위키백과에 따르면 아래에 나오는 Swift를 만들었다고 나와있다.))을 애플이 스카우트했다. 물론 프로젝트는 여전히 오픈 소스다.[22]

위에서 언급했듯, 애플의 거의 모든 제품은 Objective-C 기반이기 때문에, macOS이나 iOS용 프로그램을 작성하려면 필수적으로 익혀야 한다. 게다가 개발용 IDE인 Xcode가 맥에만 출시됐기 때문에[23], 일단 맥 컴퓨터를 구입하도록 하자.

현재는 기존 Objective-C로 개발하는 경우는 없다고 보면 되고[24], 그나마 있는 일도 예전에 Objective-C로 짜여진 앱을 Swift로 변환하는 일 정도이다. 네이티브 iOS 개발을 시작할 사람은 당연히 Swift로 시작해야한다.


5. 위기[편집]


파일:external/lh6.googleusercontent.com/dev_01-1.jpg
WWDC 2014에서 새로운 프로그래밍 언어인 Swift가 발표되었다. 더 간단한 표현, 스크립트 언어와 같은 실시간 코드 실행 등의 강력한 성능을 갖추고 Objective-C의 뒤를 잇는 애플의 차세대 프로그래밍 언어로 자리매김 할 것이라는 팀 쿡크레이그 페더리기의 선언 하에 앞으로는 Swift를 중심으로 개발자 지원이 이루어질 것으로 보인다. Objective-C는 앞으로도 레거시 프로그래밍 언어로 계속 지원이 될 수 있고 심지어 기존 Objective-C 코드 사이에 Swift 코드를 섞어 쓸 수도 있는 등 아직까지는 여러가지 배려가 이루어지는 상황이지만 애플의 레거시 배려에 안주하다가는 어떤 꼴이 나는지는 Carbon이 64비트 시대에 어떻게 토사구팽을 당했는지, 로제타 VM이 얼마나 신속하게 퇴출되었는지, Cocoa에서의 Java 지원이 지금 어떤 꼴인지를 생각하면 뻔한 일이다. 애플은 게으른 개발사, 개발자를 다독이는 곳이 아닌지라 서드파티 입장에서는 빠르게 발 맞춰 전환하는 수밖에 없을 듯하다.

파일:external/lh6.googleusercontent.com/BpJXGeiIMAAP7If.jpg
이미 이런 사진이 흥하는 중.(...)
CC++ 문법에 익숙해진 모든 프로그래머들이 환호한건 덤


6. Cocoa 기반 언어[편집]


Swift나 Objective-C나 결국 Cocoa 프레임워크 기반 위에서 작성되기 때문에 소스코드를 놓고 살펴보면 클래스명, 메소드 명등 그리 큰 차이가 없으며 당연히 앱 라이프사이클 등에 대한 메서드 또한 동일하다. 클래스의 이름에서 NS(NeXTStep) 접두어가 빠지는 느낌은...

Objective-C를 Swift로 포팅작업을 할때 보면 이건 마치 한국어를 일본어로 번역하는 기분으로 작업이 가능하다. 일본어를 모르면?


7. 관련 문서[편집]




파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 2024-08-20 23:14:27에 나무위키 Objective-C 문서에서 가져왔습니다.


[1] 그래서 표준 파운데이션 프레임워크를 보면 넥스트의 흔적이 많이 남아있다. NSDictionary, NSString의 접두어인 NS는 모두 넥스트의 운영체제였던 넥스트스텝의 준말.[2] Objective-C와 스몰토크는 서로 사용하는 특수문자가 매우 다르기 때문에 문법이 비슷하다고 보기는 힘들다.[3] 초창기 Objective-C 컴파일러는 Objective-C 코드를 일단 순수 C 코드로 번역한 후, 이것을 컴파일해 바이너리 결과를 뱉는 형태로 구현됐다. 물론 지금은 Objective-C 코드에서 바로 바이너리로 직행한다. C++ 컴파일러의 발전사를 그대로 따라갔다. 물론, 바이너리로 바로 변환하는 것보다 C로 변환한 후, C 컴파일러가 바이너리를 만들게 하는 쪽이 훨씬 쉽기 때문에, Objective-C나 C++뿐 아니라 상당수 언어가 초기에는 C 코드로 변환하는 식으로 개발되고, 나중에 인기를 얻고 퍼포먼스가 중요해지면 그 때 가서 직접 바이너리를 만드는 식으로 개선된다.[4] 지금은 사라진, 애플의 공식 언어 명세서 'Objective-C 프로그래밍 언어(The Objective-C Programming Language)'에서는 'A valid C code is also a valid Objective-C code'라고 서술했었다. 즉, Objective-C 소스 코드 파일(*.m) 내에서는 'C 코드 == Objective-C 코드'라는 것.[5] 사실 이 점이 안드로이드와 애플 쪽 OS들의 가장 큰 차이다. 안드로이드는 자바 기반이라 코드를 구동할 때 Dalvik Virtual Machine이라는 JVM기반의 커스텀된 가상머신을 쓰기 때문. [6] OS X은 libobjc.A.dylib, Windows는 objc.dll.[7] C++의 창시자인 비아네 스트로스트룹(Bjarne stroustrup)도 C++이 지나치게 전문가 전용 언어가 되었다고 비판하였다. 현재 C++ 표준은 ISO 위원회에서 정하는데, 이 위원회 인물들이 개발자라기보다는 (이론에 충실한) 전문가에 가깝기 때문에 그렇게 된 것 같다고.[8] GCC, Clang, MSVC[9] https://en.cppreference.com/w/cpp/compiler_support[10] C와의 호환성이 높은 편이긴 하지만, 객체 지향 프로그래밍뿐만 아니라 일반화 프로그래밍 및 여러가지 다른 프로그래밍 패러다임 대부분을 탑재하여 뷔페식 언어가 되었다.[11] 이 또한 Objective-C의 특징으로, 우리가 흔히 설계도라고 생각하는 클래스 그 자체도 객체로 존재하며, 당연히 클래스 메서드라는 것도 존재한다. 이 클래스 객체는 또 그들끼리의 상속 관계가 있어, 클래스 객체의 수퍼 클래스는 메타 객체라는 통괄 객체로 이어져있다.[12] 더 정확하게 말하자면, 모든 메서드 호출(==메시지 전송)이 컴파일 시간에 저 objc_msgSend 함수 호출로 치환된다.[13] 하지만, C++는 메서드 호출이 CPU 한 사이클(점프 명령)로 이루어진다. (물론 매개 변수 전달 등을 합치면 몇 사이클 더 필요하다.) 이것에 비하면 Objective-C의 메서드 호출에는 엄청난 시간이 소요되는 셈. 특히, 객체 지향 언어는 메서드 호출이 초당 수천 번 이상 이루어지는데, 얼마나 많은 명령어가 필요할 지 생각해보라. 이것이 바로 Objective-C를 비판하는 사람들의 주된 주장이다. 언어 자체가 지나치게 느리다는 것. 사실 퍼포먼스는 생산성에 반비례하는 경향이 있고, Objective-C의 생산성이 C++보다는 나은 편이기 때문에 그냥 언어의 특성으로 볼 수도 있다.[14] 아까 언급한 클래스 구조체에는 cache라는 해시 테이블이 들어있다. objc_msgSend는 일단 이 캐시 해시 테이블을 뒤진 후 나오는 게 없으면 그 때부터 저 긴 메서드 검색을 시작한다. 찾으면 메서드 이름(셀렉터; Selector)을 키 삼아 캐시에 저장하고, 못 찾으면 식별 불가능 셀렉터(unrecognized selector) 예외를 터트린다.[15] 대부분의 경우는 게임이다. 사실, C++로 작성하는 편이 퍼포먼스뿐만 아니라, 포팅에도 유리하기 때문에 맥에서도 게임은 대부분 이런 식으로 만든다. 아니, 차라리 다른 플랫폼에서 C++로 만들어진 게임을 맥으로 포트하는 경우가 사실 더 많다.[16] 물론 이렇게 하면 코코아를 사용할 수 없어 최신 시스템 API에 접근하지 못한다는 부작용이 있기 때문에, 그 절충안으로 내부 엔진은 C++로 작성하되 UI 부분만 Objective-C를 사용하기도 한다.[17] 그런데 문제는, 저 소스 코드가 완벽하게 범용성을 고려하고 작성하지 않아서, 다른 플랫폼에서 컴파일을 시도하면 특정 헤더 파일이 없다고 백이면 백 오류가 뜬다. 게다가 저 헤더 파일은 맥에만 있다! 컴파일 미, 이프 유 캔.[18] 유닉스 플랫폼의 Étoilé 프로젝트가 바로 이 그누스텝을 적극적으로 이용한 데스크탑 환경이다.[19] JetBrains사의 IDE들처럼 이러한 인자 레이블 기능을 자체적으로 지원하는 에디터도 있다.[20] 이는 개념적으로 매우 어렵기도 하지만 사실 교재 문제도 크다. 언어의 점유율이 급속도로 높아지긴 했으나, 가시권에 들어온지는 얼마 안 된 언어이기 때문에, 쓸 만한 교재가 매우 부족하다. BNR이 이쪽에서 바이블 취급을 받고 있지만 이것도 사실 타 언어의 좋은 교재들에 비하면 잘 짜여진 교재라고 보기는 힘들다. 현재로선 경쟁자들이 거의 없고 있는것도 워낙 허접해서 독보적인 위치를 차지하고 있을뿐.[21] 대략 8~9년 전 쯤 얘기인데 잡스가 여전히 여기에 뒤끝이 남아서 GCC, Samba 등을 맥에서 내칠려고 한다는 카더라가 있다. 굳이 그런게 아니더라도 GNU쪽 눈치보며 기술 공개하는게 애플같은 기업 입장에서 석연치 않은 것은 당연하다.[22] LLVM 컴파일러 셋은 Clang이라는 프론트엔드가 Objective-C 코드를 해석해 IR이라고 하는 LLVM만의 중간 언어로 번역한 후, 이것을 다시 LLVM의 백엔드가 바이너리로 옮기는 것이다. 이 LLVM/Clang은 컴파일러 선택 메뉴에 'Apple LLVM'이라는 형식으로 존재하고, LLVM+GCC 조합은 OS X 매버릭스부터 제거되었다. 문제는 이 Clang이 신생 컴파일러라서, 수십년간의 최적화가 쌓인 GCC에 비하면 아직 생성된 바이너리의 최적화 수준이 떨어진다는 것. 대신 컴파일 속도는 10~20% 빠르다고 한다.[23] 구글의 안드로이드 개발도구인 안드로이드 스튜디오는 맥에서도 실행 가능하지만 애플의 iOS 개발도구인 Xcode는 윈도우에서 실행이 불가능한, 익숙한 상황이다.[24] 아주 없지는 않다. React Native의 iOS/macOS 네이티브 모듈은 아직 Objective-C로 작성된다.