[Objective-C] Objective-C 프로그램
출처 : OS X 구조를 이해하면서 배우는 Objective-C Chap 2.
Notice : 정리자(돼지왕 왕돼지)가 remind 하고 싶은 내용이나 모르는 내용 기반으로 정리하는 것이기 때문에 구체적인 내용은 책을 사서 보시기를 권장드립니다.
2.1. 객체와 메시지
* 2.1.1. 메시지 표현식
* 2.1.2. 메시지 셀렉터
-
함수명(메서드명)을 메시지 셀렉터(message selector) 또는 셀렉터(selector) 라고도 부른다.
-
인수가 있는 키워드는 콜론도 셀럭터에 포함되므로 주의
즉 copy 와 copy: 는 다른 셀렉터.
-
메시지 키워드는 변수의 명명규칙에 따라 이름을 지으며, 소문자로 시작하는 것이 관례
-
메시지에 인수가 있으면 메시지 전체가 영어 문장처럼 읽히도록 메시지 키워드를 쓰는 것이 관례이다.
또한 인수가 여러 개라면 메시지 키워드는 각각의 인수가 무엇을 뜻하는지를 나타낸다.
-
인수마다 메시지 키워드를 대응시키면 프로그램이 길어지지만 코드의 가독성은 좋아진다.
-
자동완성이 안 되는 환경에서는 클래스 레퍼런스 등에서 셀렉터를 복사해서 붙여 넣는 것이 좋다.
* 2.1.3. 인스턴스 생성과 초기화
-
클래스명에 메시지 alloc 을 보내면 인스턴스가 새로 하나 만들어진다.
이렇게 만든 인스턴스는 메모리에 필요한 영역이 확보되었다는 것일 뿐이므로 보통은 이 다음에 바로 초기화해야 한다.
초기화 메서드는 초기자(initializer)라고 부른다.
-
Cocoa 는 초기자가 init 이거나 메서드명이 init 으로 시작돼야 한다.
-
인스턴스를 생성할 때 늘 alloc 메시지 표현식 다음에 바로 초기자가 오도록 적는 습관을 길러야 한다.
-
초기화가 인스턴스 정보를 리셋(reset) 하는 것은 아니다.
초기자에서 하는 초기화는 인스턴스가 생성된 직후 한 번만 이루어진다.
인스턴스 변수값을 초깃값으로 돌리는 등의 리셋에 해당하는 처리가 필요하면 초기자가 아닌 다른 메서드를 사용해야 한다.
2.2. 클래스 정의
* 2.2.1. 클래스 인터페이스
-
@interface 의 @end 는 Objective-C 에 도입된 컴파일러 지시자(compiler directive) 라고 부르는 식별자.
컴파일러 지시자는 모두 @ 로 시작하므로 C 언어의 컴파일러 지시자와 구별이 가능하다.
-
클래스명은 변수명이나 함수명과 같으면 안 된다.
-
YES 는 0이 아닌 값, NO 는 0으로 정의되어 있다.
-
C99 에는 BOOL 형으로 _Bool 이 있다.
C++ 에는 bool 형이 있다.
Objective-C 의 BOOL 형은 char 형으로 typedef 정의되어 있다.
BOOL 형이 이렇게 typedef 로 정의되어 있다는 것을 이용해서 코드를 작성해서는 안 된다.
-
id 형을 사용하는 것은 추천되지 않는다.
형식을 꼭 지정해서 사용하자.
* 2.2.2. 클래스 구현 부분
* 2.2.3. 클래스 정의 예제
2.3. 컴파일
* 2.3.1. 간단한 컴파일 방법
-
Objective-C 는 C 컴파일러인 clang 을 사용해서 컴파일한다.
-
Cocoa 환경에서는 시스템이 제공하는 클래스 및 함수를 프레임워크(framework)라는 구조를 가진 동적 라이브러리로 제공한다.
특히 Foundation 프레임워크는 Objective-C 의 기본적인 기능을 지원하므로 Mac OS X 와 iOS 양쪽에 들어가 있다.
-
header 와 implementation 을 하나의 파일에 넣어서 아래와 같이 컴파일 할 수 있다.
> clang a.m -framework Foundation
-framework 는 프레임워크를 지정하는 옵션으로, -framework Foundation 는 컴파일(그리고 링크) 할 때 Foundation 프레임워크를 링크한다는 의미이다.
이 떄 output 파일 이름을 지정하지 않으면 a.out 이 생성될 것이다.
이 녀석은 실행파일이다.
> ./a.out
실행 파일명을 지정하려면 -o 옵션을 사용해야 한다.
또한 컴파일할 때 경고를 자세히 출력하고 싶다면 -Wmost 나 -Wall 을 사용한다.
* 2.3.2. 분할 컴파일
-
컴파일에서 링크까지 한번에 끝내기 위해서는 아래와 같이 컴파일을 수행한다.
> clang -o outputFileName main.m test.m -framework Foundation
분할 컴파일 하기 위해서는...
> clang -c main.m
> clang -c test.m
> clang -o outputFileName main.o test.o -framework Foundation
2.4. 프로그램 작성법
* 2.4.1. 하이브리드 언어
-
Objective-C 는 C 언어에 객체지향 개념을 넣은 언어이다.
완전히 객체지향으로 작성해도 되고 기존 방법처럼 C 언어 표기와 객체를 혼용해도 된다.
이런 성질 때문에 Objective-C 를 하이브리드 언어라 부르기도 한다.
-
언제 Objective-C 에서 C 언어 함수를 사용할까?
이미 잘 작동하는 함수 모듈을 그대로 사용하고 싶을 때
유닉스 시스템 호출 같은 C 언어로 만든 인터페이스를 사용할 때
특정 객체와 관계없는 수학용, 계산용 루틴이 있을 때
클래스 정의에서 어떤 메서드 안에서만 사용할 때 ( 실행 속도가 중요할 때 )
* 2.4.2. C 함수 이용 방법
-
C 함수 정의만 들어 있는 소스 파일은 다른 C 프로그램처럼 확장자가 .c 인 파일로 작성한다.
단, 함수 속에 (Objective-C 의) 메서드 호출이 있거나 (Objective-C의) 클래스 정의 관련 정보를 사용한다면 C 소스 파일로 컴파일 할 수 없으므로 확장자를 .m 으로 바꿔야 한다.
그리고 그와 함께 대응하는 클래스 인터페이스를 포함하는 헤더 파일도 임포트해야 한다.
-
아래 명령어로 c 를 포함해서 컴파일할 수 있다.
> clang -o outFileName main.m util.c test.m -framework Foundation
-
클래스 구현 파일 속에 함수 정의도 가능하다.
다만, 메서드 정의에 필요한 함수처럼 클래스 구현에 직접 관계가 있는 것으로 제한해야 한다.
함수 정의는 @implementation 앞, @implemenation 과 @end 사이, @end 뒤 어디에 있어도 괜찮다. ( 단, @end 뒤에 함수가 존재하는 경우에는 프로토타입 선언이 필요하다. )
구현 파일에서 지역적인 함수라면 static 지정자를 쓰는 게 좋다.
-
구현 파일에 정의된 함수라도 인스턴스 변수나 self 는 그 함수 내부에서 참조하지 못한다.
다만, 실인수로 함수에 넘기는 방법은 가능하다.
인스턴스 변수나 self 에 접근하려면 메서드로 정의하는 게 올바른 방법이다.
* 2.4.3. 정적 변수 정의
-
함수나 메서드 정의 밖에서 정의된 변수 및 static 지정자가 붙은 변수는 정적인 변수, 달리 말해 프로그램을 실행하기 시작해서 종료할 때까지 계속 존재하는 변수이다.
메서드 정의에서도 static 을 붙여서 정적 변수를 사용할 수 있지만, 기본 C 프로그래밍과는 다르므로 주의해야 한다.
-
인스턴스 객체를 여러 개 만들 수 있는데 정적 변수 선언은 한 번 뿐이다.
따라서 여러 인스턴스에서 정적 변수를 공유한다.
* 2.4.4. 헤더 파일 임포트
-
Objective-C 는 #import 라는 전처리기 지시자(preprocessor directive)를 사용한다.
#include 와 달리 #import 는 한 번 읽은 헤더 파일을 여러 번 인클루드하지 않는다.
-
C 언어 프로그래밍은 같은 헤더 파일을 여러 번 읽어도 문제가 발생하지 않도록 다음과 같은 방법으로 문제를 회피한다.
#ifndef __MYLIB_H__
#define __MYLIB_H__
// 헤더 파일 내용 작성
#endif /* __MYLIB_H__ */
__MYLIB_H__ 는 헤더 파일 고유의 매크로명이다.
처음으로 이 헤더 파일을 읽었을 때는 해당 매크로 정의가 없으므로 #ifndef 부터 #endif 사이의 내용을 처리하고 매크로 __MYLIB_H__ 도 이 때 정의한다.
그 후 이 헤더 파일을 읽으면 이미 __MYLIB_H__ 매크로가 정의되어 있으므로 #ifndef 부터 #endif 사이의 내용은 건너뛴다.
하지만 헤더 파일을 작성할 떄마다 이런 내용을 추가하는 건 귀찮기도 하고 실수하기도 쉬우므로 Objective-C 는 #include 대신 #import 로 헤더 파일을 좀 더 간편하게 다룬다.
cf) Cocoa API 는 오픈 소스가 아니지만 그 기원인 OPENSTEP 의 기본 부분 사양인 OpenStep 을 NeXT 사가 공개했다.
다음 글 : [Objective-C] 상속과 클래스
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[Objective-C] 객체 형식과 동적 결합 (0) | 2017.12.26 |
---|---|
[Objective-C] 상속과 클래스 (0) | 2017.12.25 |
[Objective-C] 객체 기반 소프트웨어 작성 (0) | 2017.12.23 |
[xcode] suppressing warning - incompatible pointer types sending … (0) | 2017.12.22 |
[ios] TableView 의 Height dynamic 하게 바꾸기 (0) | 2017.12.21 |
댓글