본문 바로가기
  • 그냥 하자
iOS

Chap4-1. enum,typedef,전처리기,preprocessor,define,전방선언,import,조건부컴파일,if,elif,배열,함수,구조체,sdk,nsobject,클래스,메모리생성,메모리해제,dealloc,autoreleasepool,nsdate,nsdateformatter,nslocale

by Mash 2012. 3. 22.
반응형

이 글은 아래의 출처를 수정하여 작성한 글 임을 밝힌다. 

<출처 : http://wwwww.kr/30792>

 
enum

- enum은 열거형 상수를 선언하는 예약어로 정수 상수를 저장합니다.
- enum 열거형이름 {열거형 상수, …..}; 형태로 정의합니다.
- 값을 지정하지 않으면 이전 값에 1을 더하게 되고 처음 값을 지정하지 않으면 첫 번째는 0을 가지게 되며 다음부터는 1씩 증가합니다.
- 중간에 초기값을 지정하면 그 값부터 1씩 증가합니다.
- 할당 가능한 값의 범위를 지정하기 위해서 많이 이용합니다.
- 컴파일러는 정수와 동일하게 취급합니다.
- 열거형 변수 선언 : enum 열거형이름 변수명;

 

01.1.Command Line Tool 프로젝트 생성(EnumTest)
02.2.EnumTest.m 파일 작성
03.#import <Foundation/Foundation.h> 
04.int main ()
05.
06.enum Menu {Input = 1, Output, Exit}; 
07.int menu; 
08.NSLog (@"메뉴를 입력하세요: "); 
09.scanf ("%d", &menu);
10.switch ((enum Menu)menu)
11.
12.case Input: 
13.NSLog(@"입력을 선택하셧습니다");
14.break
15.case Output:
16.NSLog(@"출력을 선택하셧습니다");
17.break;
18.case Exit:
19.NSLog(@"종료를 선택하셧습니다");
20.break;
21.default
22.NSLog (@"잘못 입력하셨습니다."); 
23.break;
24.}
25.return 0; 
26.}


typedef
- 자료형의 이름에 별명을 붙여서 사용하고자 하는 경우 사용하는 예약어 입니다.
- typedef [변경하고자 하는 자료형] [별명으로 사용할 이름]; 
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef unsigned long NSUInteger;
#else
typedef unsigned int NSUInteger;
#endif

NSInteger : 정수
NSUInteger : 부호없는 정수
CGFloat  : 실수
NSTimeInterval :

#define = 매크로

cf.
M_PI (ㅠ값) : 3.141592………..
Degree ToRadian - 아이폰에서는 각도가 라디언값으로 적용되므로 일반 각을 라디언으로 변환
 - 사용자가 작성하는 매크로이므로 상단에 작성해야 함

프레임워크는 헤드파일이 objective-c

C언어파일 형태 - 일반 헤더파일

 

 

전처리기(Preprocessor)
- 전처리기는 Objective-C 프로그램을 분석하기 전에 먼저 처리하는 명령문입니다.
- 전처리기는 #으로 시작합니다.
- 전처리기의 내용은 반드시 Objective-C 문법일 필요는 없습니다.
- C언어의 헤더파일도 사용이 가능합니다.
- 전처리문은 Objective-C 컴파일러의 내용보다 먼저 컴파일 되어야 하므로 일반적으로 가장 상단에 작성합니다.

 

 

#define
- #define은 상수 값에 심벌 명을 부여하는 것입니다.
- 정의할 때는 #define 심벌이름 값 의 형태로 정의됩니다.
- #define TRUE 1 이라고 정의하면 TRUE는 이제부터 1이 됩니다.
- 주의할 점은 ;으로 끝나지 않는다는 것입니다.
- 위의 매크로는 1이 입력해야 하는 자리에 TRUE를 입력해도 된다는 의미입니다.
- 컴파일 시 매크로는 전부 확장되어집니다.
- 디버깅시에는 매크로의 값을 확인할 수 없습니다.
- 연산자를 재정의해서 사용하는 것도 가능합니다.
- #define AND $$ 및 #define SAME == 이런 문장도 가능합니다.
- 여러 줄에 걸친 define 도 가능하며 이 경우에는  \를 붙여서 정의해야 합니다.
- 메서드 처럼 정의하는 것도 가능합니다.
- 매개 변수가 필요하면 매크로 심벌 다음에 (매개변수명)을 이용하면 됩니다.

01.#import <Foundation/Foundation.h>
02.#define AND &&
03.#define OR ||
04.#define EQUAL ==
05.int main (int argc, const char * argv[]) {
06.NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
07.int year;
08.NSLog(@"년도를 입력하세요");
09.scanf("%i", &year);
10.if(year % 4 EQUAL 0 AND year % 100 != 0 OR year % 400 EQUAL 0)
11.{
12.NSLog(@"%i년은 윤년입니다", year);
13.}
14.else
15.{     
16.NSLog(@"%i년은 윤년이 아닙니다", year);    
17.}
18.[pool drain];
19.return 0;
20.}
01.#import <Foundation/Foundation.h>
02.#define LEAP_CHECK(year) y%4==0 && y%100!=0 || y % 400 == 0
03.int main (int argc, const char * argv[]) {
04.NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
05.int y;
06.NSLog(@"년도를 입력하세요:");
07.scanf("%i", &y);
08.if(LEAP_CHECK(y) == YES)
09.NSLog(@"%년은 윤년입니다.", y);
10.else
11.NSLog(@"%d년은 윤년이 아닙니다.", y);   
12.[pool drain];
13.return 0;
14.}

 

전방선언

01.A.h
02.#import "B.h"
03.@class 클래스명;
04.@class B; // import된게 아니라 B라는 클래스가 있다 라고 하고 넘어가는 것임.
05.@interface A : NSObject
06.{
07.B * Obj;
08.}
09.@end
1.A.m
2.#import "B.h"
3.#import "A.h"
4.@implementation A
5.@end
6.@implementation B
7.@end
1.B.h
2.#import "A.h"
3.@interface B : NSObject
4.{
5.A * Obj;
6.}
7.@end

전방선언을 반드시 해야하는 경우
- A.h에서 B.h를 부르는데 B.h는 A.h를 부르고 루프에 걸린다.
- 되도록 사용하지 마.

 

 

#import
- 뒤에 나오는 파일을 포함시켜서 컴파일 해달라는 의미입니다.
- 현재 프로젝트 폴더에 있는 파일을 포함시키고자 하는 경우는 “파일명”으로 기재
- 시스템 헤더파일 디렉토리에 있는 파일을 포함시키고자 하는 경우는 <파일명>으로 기재
- 헤더파일이 프레임워크인 경우에는 <프레임워크이름/헤더파일명>으로 형태로 기재합니다.
- 기본적인 시스템 헤더 디렉토리는 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers
- 선언부에서 다른 클래스의 이름이 필요한 경우에는 import를 하지 않고 아래처럼 선언해도 됩니다.
- @class 클래스명;
구현 파일에서 import를 해야합니다.
이를 클래스의 전방 선언이라고 합니다.

 
조건부 컴파일
- 조건에 맞는 경우만 컴파일하라는 지시문으로 프로그램이 시스템의 특정한 매개변수에 의해 의존적이어야 하는 경우가 있는데 이런 경우 사용할 수 있는 방법입니다.
- #ifdef, #endif, #else, #ifndef
#ifdef는 다음에는 매크로가 정의되어 있으면 수행할 문장을 기재하고 #else는 매크로가 정의되어 있지 않다면 수행할 문장을 기재하고 #endif는 종료를 나타내는 구문입니다.
#ifndef는 #ifdef와 반대되는 구문입니다.
ex)

1.#ifdef MAC_OS_X
2.#define DATADIR “/uxn1/data”
3.#else
4.#define DATADIR “\usr\data”
5.#endif

MAC_OS_X라는 매크로가 있다면 디렉토리는 /uxn1/data
아니면 \usr\data //유닉스에서 돌아가도록

주의 : 맥은 디렉토리가 슬러시(/)

# ifdef 는 아이팟,아이폰,아이패드 에서 운영체제에따라 보여지는게 다르게 할 경우 유용함

 

#if와 #elif
조건이 참일 때만 수행하는 문장을 만들 때 사용하는 구문입니다.
NSString.h 파일에 다음과 같이 정의되어 있습니다.
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
@class NSError;
@class NSLocale;
@class NSURL;
#endif

 #undef
매크로 심벌을 삭제하고자 하는 경우 사용하는 예약어

 
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)//os버전을 판단하는 매크로함수
@class NSError;
@class NSLocale;
@class NSURL;
#endif

 

 

배열
- Objective-C의 배열은 참조형만 가능하므로 일반 자료형의 배열을 생성하고자 하면 C 스타일의 배열을 사용해야 합니다.
- C언어 타입의 배열은 자료형 배열명 [크기] 로 선언합니다.
- 배열의 요소에 접근할 때는 배열명 [인덱스] 로 접근합니다.
- 참조형이 아니므로 메모리 할당하는 문장이 필요 없습니다.
- 참조형이 아니므로 멤버를 갖지도 않습니다.
- C스타일의 배열은 경계를 점검하지 않으므로 주의해서 사용
- 배열의 요소 개수를 구하는 방법은 sizeof 연산자를 이용해서 메모리 크기를 가지고 구해야 합니다.
- count나 length 멤버가 없으므로 배열의 요소 개수는 sizeof(배열명)/sizeof(배열명[0])으로 직접 산술 연산을 수행하여 얻어야 합니다.

 

함수
- C 타입의 함수를 선언해서 파일 내에서 사용이 가능합니다.
- 기존 C언어의 표준 함수를 호출해서 사용하기도 합니다.
예제

01.#import <Foundation/Foundation.h>
02.void printMessage (void)
03.{
04.NSLog (@"C스타일의 함수");
05.}
06.int main (int argc, const char * argv[]) {
07.NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
08.printMessage();  
09.[pool drain];
10.return 0;
11.}

 

 

예제 // 클래스 내부에서의 호출

01.#import <Foundation/Foundation.h>
02.void printMessage()
03.{
04.NSLog (@"C스타일 함수");
05.}
06.@interface Test:NSObject
07.- (void) Disp;
08.@end
09.@implementation Test
10.- (void) Disp
11.{
12.printMessage();
13.}
14.@end
15.int main (int argc, const char * argv[]) {
16.NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
17.Test *Obj = [Test new];
18.[Obj Disp]; 
19.[pool drain];
20.return 0;
21.}


 

구조체
- 여러 멤버들을 묶을 수 있는 것으로 배열과 다른 점은 멤버들의 크기가 달라도 된다는 점입니다.
- 인스턴스 변수들은 이 구조체의 형태로 메모리에 저장이 됩니다.
- 선언과 변수 생성
- 선언
struct 이름
{
   자료형 멤버명;
      ....
 }

- 구조체 변수 생성
struct 이름 변수명

- 멤버 접근 
. 연산자나 ->연산자를 이용해서 멤버에 접근합니다.
구조체는 모든 멤버를 public으로 간주합니다.

 

구조체의 사용
- 기본값 지정
struct 구조체이름 변수명 = {값나열}
struct 구조체이름 변수명 = {.멤버명=값,….}

- 구조체 내의 구조체
구조체 내에 다른 구조체 변수를 포함할 수 있습니다.
날짜만 사용하는 구조체가 필요하고 시간만 저장하는 구조체가 필요하고 이 2가지를 모두 가지는 구조체가 필요하다면 이는 아래와 같이 정의해서 사용할 수 있습니다.

struct date
{
   int year;
   int month;
   int day;
}
struct time
{
   int hour;
   int minute;
   int second;
}
struct datetime
{
   struct date sdate;
   struct time stime;
}

 

 

SDK에서 알아두면 유용한 구조체

01.struct CGPoint {
02.CGFloat x;
03.CGFloat y;
04.};
05.struct CGSize {
06.CGFloat width;
07.CGFloat height;
08.};
09.struct CGRect {
10.CGPoint origin;
11.CGSize size;
12.};
13.typedef struct _NSRange {
14.NSUInteger location;
15.NSUInteger length;
16.} NSRange;

c언어의 함수는 마음껏 불러쓸수 있지만 멤버가 될 수는 없다.


CGPoint : 좌표 구조체
CGSize : 넓이와 높이
CGRect : 위의 둘 중 하나씩 선택

CGrect rect;
rect.origin.x=?; //x좌표 변경
rect.size.width=?; // 사이즈 변경

NSRange : 위치와 길이

반응형