Objective-C 퀵 가이드

Objective-C는 Small Talk 프로그래밍 언어의 기능을 추가하여 C 프로그래밍 언어 위에 개발 된 범용 언어로 객체 지향 언어입니다. 주로 iOS 및 Mac OS X 운영 체제와 해당 응용 프로그램을 개발하는 데 사용됩니다.

처음에 Objective-C는 NeXT가 NeXTSTEP OS 용으로 개발했으며 Apple이 iOS 및 Mac OS X 용으로 인수했습니다.

객체 지향 프로그래밍

객체 지향 개발의 네 가지 기둥을 포함하여 객체 지향 프로그래밍을 완벽하게 지원합니다.

  • Encapsulation
  • 데이터 숨김
  • Inheritance
  • Polymorphism

예제 코드

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   NSLog (@"hello world");
   [pool drain];
   return 0;
}

기초 프레임 워크

Foundation Framework는 다양한 기능을 제공하며 아래에 나열되어 있습니다.

  • 여기에는 NSArray, NSDictionary, NSSet 등과 같은 확장 데이터 유형 목록이 포함됩니다.

  • 파일, 문자열 등을 조작하는 풍부한 기능 세트로 구성됩니다.

  • URL 처리, 날짜 형식, 데이터 처리, 오류 처리 등과 같은 유틸리티를위한 기능을 제공합니다.

학습 목표 -C

Objective-C를 배울 때해야 할 가장 중요한 일은 개념에 집중하고 언어 기술 세부 사항에서 길을 잃지 않는 것입니다.

프로그래밍 언어를 배우는 목적은 더 나은 프로그래머가되는 것입니다. 즉, 새로운 시스템을 설계 및 구현하고 기존 시스템을 유지하는 데 더 효과적입니다.

Objective-C 사용

앞에서 언급했듯이 Objective-C는 iOS 및 Mac OS X에서 사용됩니다. iOS 사용자 기반이 넓고 Mac OS X 사용자가 크게 증가하고 있습니다. 그리고 Apple은 품질 우선에 초점을 맞추고 Objective-C를 배우기 시작한 사람들을 위해 훌륭합니다.

지역 환경 설정

Objective-C 프로그래밍 언어에 대한 환경을 설정하려는 경우 컴퓨터에서 사용할 수있는 다음 두 소프트웨어, (a) 텍스트 편집기 및 (b) GCC 컴파일러가 필요합니다.

텍스트 에디터

이것은 프로그램을 입력하는 데 사용됩니다. 몇 가지 편집기의 예로는 Windows 메모장, OS 편집 명령, Brief, Epsilon, EMACS 및 vim 또는 vi가 있습니다.

텍스트 편집기의 이름과 버전은 운영 체제에 따라 다를 수 있습니다. 예를 들어 메모장은 Windows에서 사용되며 vim 또는 vi는 Linux 또는 UNIX뿐만 아니라 Windows에서도 사용할 수 있습니다.

편집기로 만든 파일을 소스 파일이라고하며 프로그램 소스 코드를 포함합니다. Objective-C 프로그램의 소스 파일 이름은 일반적으로 ".m".

프로그래밍을 시작하기 전에 하나의 텍스트 편집기가 있고 컴퓨터 프로그램을 작성하고 파일에 저장하고 컴파일하고 마지막으로 실행할 수있는 충분한 경험이 있는지 확인하십시오.

GCC 컴파일러

소스 파일에 작성된 소스 코드는 프로그램의 사람이 읽을 수있는 소스입니다. 기계어로 변환하려면 "컴파일"되어야합니다. 그래야 CPU가 실제로 주어진 명령에 따라 프로그램을 실행할 수 있습니다.

이 GCC 컴파일러는 소스 코드를 최종 실행 프로그램으로 컴파일하는 데 사용됩니다. 프로그래밍 언어 컴파일러에 대한 기본 지식이 있다고 가정합니다.

GCC 컴파일러는 다양한 플랫폼에서 무료로 사용할 수 있으며 다양한 플랫폼에서 설정하는 절차는 다음과 같습니다.

UNIX / Linux에 설치

초기 단계는 gcc Objective-C 패키지와 함께 gcc를 설치하는 것입니다. 이것은-

$ su - $ yum install gcc
$ yum install gcc-objc

다음 단계는 다음 명령을 사용하여 패키지 종속성을 설정하는 것입니다.

$ yum install make libpng libpng-devel libtiff libtiff-devel libobjc 
   libxml2 libxml2-devel libX11-devel libXt-devel libjpeg libjpeg-devel

Objective-C의 모든 기능을 사용하려면 GNUStep을 다운로드하여 설치하십시오. 이것은 다음에서 패키지를 다운로드하여 수행 할 수 있습니다.http://main.gnustep.org/resources/downloads.php.

이제 다운로드 한 폴더로 전환하여 다음과 같이 파일의 압축을 풀어야합니다.

$ tar xvfz gnustep-startup-
      
       .tar.gz 
      

이제 다음을 사용하여 생성 된 gnustep-startup 폴더로 전환해야합니다.

$ cd gnustep-startup-<version>

다음으로 빌드 프로세스를 구성해야합니다.

$ ./configure

그러면 우리는 다음과 같이 만들 수 있습니다.

$ make

마지막으로 환경을 설정해야합니다.

$ . /usr/GNUstep/System/Library/Makefiles/GNUstep.sh

다음과 같이 helloWorld.m Objective-C가 있습니다.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
   NSLog (@"hello world");
   [pool drain];
   return 0;
}

이제 cd를 사용하여 파일이 포함 된 폴더로 전환 한 후 다음 단계를 사용하여 Objective-C 파일 인 helloWorld.m을 컴파일하고 실행할 수 있습니다.

$ gcc `gnustep-config --objc-flags` 
-L/usr/GNUstep/Local/Library/Libraries 
-lgnustep-base helloWorld.m -o helloWorld
$ ./helloWorld

다음 출력을 볼 수 있습니다.

2013-09-07 10:48:39.772 tutorialsPoint[12906] hello world

Mac OS에 설치

Mac OS X를 사용하는 경우 GCC를 얻는 가장 쉬운 방법은 Apple 웹 사이트에서 Xcode 개발 환경을 다운로드하고 간단한 설치 지침을 따르는 것입니다. Xcode를 설정하면 C / C ++ 용 GNU 컴파일러를 사용할 수 있습니다.

Xcode는 현재 developer.apple.com/technologies/tools/ 에서 사용할 수 있습니다 .

Windows에 설치

윈도우에서 Objective-C 프로그램을 실행하기 위해서는 MinGW와 GNUStep Core를 설치해야합니다. 둘 다에서 사용할 수 있습니다https://www.gnu.org/software/gnustep/windows/installer.html.

먼저 MSYS / MinGW 시스템 패키지를 설치해야합니다. 그런 다음 GNUstep Core 패키지를 설치해야합니다. 둘 다 설명이 필요없는 Windows 설치 프로그램을 제공합니다.

그런 다음 시작-> 모든 프로그램-> GNUstep-> 셸을 선택하여 Objective-C 및 GNUstep을 사용합니다.

helloWorld.m이 포함 된 폴더로 전환합니다.

다음을 사용하여 프로그램을 컴파일 할 수 있습니다.

$ gcc `gnustep-config --objc-flags` 
-L /GNUstep/System/Library/Libraries hello.m -o hello -lgnustep-base -lobjc

다음을 사용하여 프로그램을 실행할 수 있습니다.

./hello.exe

우리는 다음과 같은 출력을 얻습니다.

2013-09-07 10:48:39.772 tutorialsPoint[1200] hello world

Objective-C 프로그래밍 언어의 기본 구성 요소를 연구하기 전에 다음 장에서 참조 할 수 있도록 최소한의 Objective-C 프로그램 구조를 살펴 보겠습니다.

Objective-C Hello World 예제

Objective-C 프로그램은 기본적으로 다음 부분으로 구성됩니다.

  • 전 처리기 명령
  • Interface
  • Implementation
  • Method
  • Variables
  • 진술 및 표현
  • Comments

"Hello World"라는 단어를 인쇄하는 간단한 코드를 살펴 보겠습니다.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass

- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

@end

int main() {
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   return 0;
}

위 프로그램의 다양한 부분을 살펴 보겠습니다.

  • 프로그램 #import <Foundation / Foundation.h> 의 첫 번째 줄은 실제 컴파일로 이동하기 전에 Objective-C 컴파일러에 Foundation.h 파일을 포함하도록 지시하는 전 처리기 명령입니다.

  • 다음 줄 @interface SampleClass : NSObject 는 인터페이스를 만드는 방법을 보여줍니다. 모든 개체의 기본 클래스 인 NSObject를 상속합니다.

  • 다음 줄 -(void) sampleMethod; 메서드를 선언하는 방법을 보여줍니다.

  • 다음 줄 @end 는 인터페이스의 끝을 표시합니다.

  • 다음 줄 @implementation SampleClass 는 SampleClass 인터페이스를 구현하는 방법을 보여줍니다.

  • 다음 줄 -(void) sampleMethod {}sampleMethod 의 구현을 보여줍니다.

  • 다음 줄 @end 는 구현의 끝을 표시합니다.

  • 다음 줄 int main () 은 프로그램 실행이 시작되는 주 함수입니다.

  • 다음 줄 /*...*/는 컴파일러에 의해 무시되며 프로그램에 주석을 추가하기 위해 추가되었습니다. 따라서 이러한 행을 프로그램에서 주석이라고합니다.

  • 다음 줄 NSLog (...) 는 Objective-C에서 사용할 수있는 또 다른 함수로 "Hello, World!"라는 메시지를 표시합니다. 화면에 표시됩니다.

  • 다음 줄 return 0; main () 함수를 종료하고 값 0을 반환합니다.

Objective-C 프로그램 컴파일 및 실행

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2017-10-06 07:48:32.020 demo[65832] Hello, World!

Objective-C 프로그램의 기본 구조를 살펴 보았으므로 Objective-C 프로그래밍 언어의 다른 기본 구성 요소를 쉽게 이해할 수 있습니다.

Objective-C의 토큰

Objective-C 프로그램은 다양한 토큰으로 구성되며 토큰은 키워드, 식별자, 상수, 문자열 리터럴 또는 기호입니다. 예를 들어, 다음 Objective-C 문은 6 개의 토큰으로 구성됩니다.

NSLog(@"Hello, World! \n");

개별 토큰은 다음과 같습니다.

NSLog
@
(
   "Hello, World! \n"
)
;

세미콜론;

Objective-C 프로그램에서 세미콜론은 문 종결 자입니다. 즉, 각 개별 문은 세미콜론으로 끝나야합니다. 하나의 논리적 엔티티의 끝을 나타냅니다.

예를 들어, 다음은 두 가지 다른 진술입니다.

NSLog(@"Hello, World! \n");
return 0;

코멘트

주석은 Objective-C 프로그램의 도움말 텍스트와 같으며 컴파일러에서 무시됩니다. 다음과 같이 / *로 시작하고 * / 문자로 끝납니다.

/* my first program in Objective-C */

주석에는 주석을 포함 할 수 없으며 문자열 또는 문자 리터럴 내에서 발생하지 않습니다.

식별자

Objective-C 식별자는 변수, 함수 또는 기타 사용자 정의 항목을 식별하는 데 사용되는 이름입니다. 식별자는 A에서 Z까지의 문자 또는 a에서 z까지의 문자 또는 밑줄 _로 시작하여 0 개 이상의 문자, 밑줄 및 숫자 (0-9)가 이어집니다.

Objective-C는 식별자 내에서 @, $ 및 %와 같은 구두점 문자를 허용하지 않습니다. Objective-C는case-sensitive프로그래밍 언어. 따라서 인력인력 은 Objective-C에서 두 가지 다른 식별자입니다. 다음은 허용되는 식별자의 몇 가지 예입니다.

mohd       zara    abc   move_name  a_123
myname50   _temp   j     a23b9      retVal

키워드

다음 목록은 Objective-C의 예약어 중 일부를 보여줍니다. 이러한 예약어는 상수, 변수 또는 기타 식별자 이름으로 사용할 수 없습니다.

자동 그밖에 스위치
단절 열거 형 레지스터 typedef
케이스 통근자 반환 노동 조합
흙손 짧은 서명되지 않은
const ...에 대한 서명
계속하다 이동 크기 휘발성 물질
기본 만약 공전 동안
하다 int 구조체 _포장 된
더블 실험 계획안 상호 작용 이행
NSObject NSInteger NSNumber CGFloat
특성 비 원자; 유지 강한
약한 unsafe_unretained; 읽기 쓰기 읽기 전용

Objective-C의 공백

공백 만 포함하는 줄 (가능하면 주석 포함)을 빈 줄이라고하며 Objective-C 컴파일러는이를 완전히 무시합니다.

공백은 Objective-C에서 공백, 탭, 개행 문자 및 주석을 설명하는 데 사용되는 용어입니다. 공백은 명령문의 한 부분을 다른 부분과 분리하고 컴파일러가 int와 같은 명령문의 한 요소가 끝나고 다음 요소가 시작되는 위치를 식별 할 수 있도록합니다. 따라서 다음 진술에서-

int age;

컴파일러가 구분할 수 있으려면 int와 age 사이에 공백 문자 (일반적으로 공백)가 하나 이상 있어야합니다. 반면에 다음 문장에서

fruit = apples + oranges;   // get the total fruit

과일과 = 사이 또는 =와 사과 사이에는 공백 문자가 필요하지 않지만 가독성을 위해 원하는 경우 일부를 포함 할 수 있습니다.

Objective-C 프로그래밍 언어에서 데이터 유형은 다양한 유형의 변수 또는 함수를 선언하는 데 사용되는 광범위한 시스템을 나타냅니다. 변수의 유형에 따라 저장 공간에서 차지하는 공간과 저장된 비트 패턴이 해석되는 방식이 결정됩니다.

Objective-C의 유형은 다음과 같이 분류 할 수 있습니다.

Sr. 아니. 유형 및 설명
1

Basic Types −

이들은 산술 유형이며 (a) 정수 유형 및 (b) 부동 소수점 유형의 두 가지 유형으로 구성됩니다.

2

Enumerated types −

이들은 다시 산술 유형이며 프로그램 전체에서 특정 이산 정수 값에만 할당 될 수있는 변수를 정의하는 데 사용됩니다.

The type void −

유형 지정자 void 는 사용 가능한 값이 없음을 나타냅니다.

4

Derived types −

여기에는 (a) 포인터 유형, (b) 배열 유형, (c) 구조 유형, (d) 공용체 유형 및 (e) 함수 유형이 포함됩니다.

배열 유형 및 구조 유형을 집합 적으로 집계 유형이라고합니다. 함수의 유형은 함수의 반환 값 유형을 지정합니다. 다음 섹션에서 기본 유형을 살펴보고 다른 유형은 다음 장에서 다룰 것입니다.

정수 유형

다음 표는 저장 크기 및 값 범위와 함께 표준 정수 유형에 대한 세부 정보를 제공합니다.

유형 저장 크기 값 범위
1 바이트 -128에서 127 또는 0에서 255
부호없는 문자 1 바이트 0에서 255
서명 된 문자 1 바이트 -128에서 127
int 2 또는 4 바이트 -32,768 ~ 32,767 또는 -2,147,483,648 ~ 2,147,483,647
서명되지 않은 정수 2 또는 4 바이트 0 ~ 65,535 또는 0 ~ 4,294,967,295
짧은 2 바이트 -32,768에서 32,767
서명되지 않은 짧은 2 바이트 0에서 65,535
4 바이트 -2,147,483,648에서 2,147,483,647
부호없는 긴 4 바이트 0에서 4,294,967,295

특정 플랫폼에서 유형 또는 변수의 정확한 크기를 얻으려면 다음을 사용할 수 있습니다. sizeof운영자. sizeof (type) 표현식 은 객체 또는 유형의 저장 크기 (바이트 )를 산출합니다. 다음은 모든 시스템에서 int 유형의 크기를 얻는 예입니다.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for int : %d \n", sizeof(int));
   return 0;
}

위의 프로그램을 컴파일하고 실행하면 Linux에서 다음과 같은 결과가 생성됩니다.

2013-09-07 22:21:39.155 demo[1340] Storage size for int : 4

부동 소수점 유형

다음 표는 저장 크기와 값 범위 및 정밀도와 함께 표준 부동 소수점 유형에 대한 세부 정보를 제공합니다.

유형 저장 크기 값 범위 정도
흙손 4 바이트 1.2E-38에서 3.4E + 38 소수점 6 자리
더블 8 바이트 2.3E-308에서 1.7E + 308 소수점 이하 15 자리
롱 더블 10 바이트 3.4E-4932에서 1.1E + 4932 소수점 19 자리

헤더 파일 float.h는 이러한 값과 프로그램에서 실수의 이진 표현에 대한 기타 세부 정보를 사용할 수있는 매크로를 정의합니다. 다음 예제는 float 유형과 범위 값이 차지하는 저장 공간을 인쇄합니다.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for float : %d \n", sizeof(float));
   return 0;
}

위의 프로그램을 컴파일하고 실행하면 Linux에서 다음과 같은 결과가 생성됩니다.

2013-09-07 22:22:21.729 demo[3927] Storage size for float : 4

무효 유형

void 유형은 사용 가능한 값이 없음을 지정합니다. 세 가지 상황에서 사용됩니다.

Sr. 아니. 유형 및 설명
1 Function returns as void

Objective-C에는 값을 반환하지 않거나 void를 반환한다고 말할 수있는 다양한 함수가 있습니다. 반환 값이없는 함수는 반환 유형이 void입니다. 예를 들면void exit (int status);

2 Function arguments as void

Objective-C에는 매개 변수를 허용하지 않는 다양한 기능이 있습니다. 매개 변수가없는 함수는 void로 받아 들일 수 있습니다. 예를 들면int rand(void);

이 시점에서 void 유형을 이해하지 못할 수 있으므로 계속 진행하고 다음 장에서 이러한 개념을 다룰 것입니다.

변수는 프로그램이 조작 할 수있는 저장 영역에 주어진 이름 일뿐입니다. Objective-C의 각 변수에는 변수 메모리의 크기와 레이아웃을 결정하는 특정 유형이 있습니다. 해당 메모리 내에 저장할 수있는 값의 범위 변수에 적용 할 수있는 연산 집합입니다.

변수 이름은 문자, 숫자 및 밑줄 문자로 구성 될 수 있습니다. 문자 또는 밑줄로 시작해야합니다. Objective-C는 대소 문자를 구분하므로 대문자와 소문자는 구별됩니다. 이전 장에서 설명한 기본 유형에 따라 다음과 같은 기본 변수 유형이 있습니다.

Sr. 아니. 유형 및 설명
1

char

일반적으로 단일 옥텟 (1 바이트)입니다. 이것은 정수 유형입니다.

2

int

기계의 가장 자연스러운 정수 크기입니다.

float

단 정밀도 부동 소수점 값입니다.

4

double

배정 밀도 부동 소수점 값입니다.

5

void

유형이 없음을 나타냅니다.

Objective-C 프로그래밍 언어는 또한 다양한 다른 유형의 변수를 정의 할 수 있도록하는데, 이는 열거 형, 포인터, 배열, 구조, 결합 등과 같은 후속 장에서 다룰 것입니다.이 장에서는 기본적인 변수 유형 만 살펴 보겠습니다.

Objective-C의 변수 정의

변수 정의는 변수에 대한 저장소를 생성 할 위치와 양을 컴파일러에 알리는 것을 의미합니다. 변수 정의는 데이터 유형을 지정하고 다음과 같이 해당 유형의 하나 이상의 변수 목록을 포함합니다.

type variable_list;

여기, type char, w_char, int, float, double, bool 또는 사용자 정의 개체 등을 포함한 유효한 Objective-C 데이터 유형이어야합니다. variable_list쉼표로 구분 된 하나 이상의 식별자 이름으로 구성 될 수 있습니다. 몇 가지 유효한 선언이 여기에 표시됩니다.

int    i, j, k;
char   c, ch;
float  f, salary;
double d;

라인 int i, j, k;둘 다 변수 i, j 및 k를 선언하고 정의합니다. 컴파일러가 int 유형의 i, j 및 k라는 변수를 생성하도록 지시합니다.

변수는 선언에서 초기화 (초기 값 할당) 할 수 있습니다. 이니셜 라이저는 다음과 같이 등호와 상수 표현식으로 구성됩니다.

type variable_name = value;

몇 가지 예는-

extern int d = 3, f = 5;    // declaration of d and f. 
int d = 3, f = 5;           // definition and initializing d and f. 
byte z = 22;                // definition and initializes z. 
char x = 'x';               // the variable x has the value 'x'.

이니셜 라이저가없는 정의 : 정적 저장 기간이있는 변수는 암시 적으로 NULL로 초기화됩니다 (모든 바이트의 값은 0). 다른 모든 변수의 초기 값은 정의되지 않습니다.

Objective-C의 변수 선언

변수 선언은 주어진 유형과 이름을 가진 하나의 변수가 존재한다는 것을 컴파일러에 보장하여 컴파일러가 변수에 대한 완전한 세부 사항없이 추가 컴파일을 진행할 수 있도록합니다. 변수 선언은 컴파일시에만 의미가 있으며 컴파일러는 프로그램 연결시 실제 변수 선언이 필요합니다.

변수 선언은 여러 파일을 사용하고 프로그램 링크시 사용할 수있는 파일 중 하나에 변수를 정의 할 때 유용합니다. 당신은 사용할 것입니다extern어떤 장소에서든 변수를 선언하는 키워드. Objective-C 프로그램에서 변수를 여러 번 선언 할 수 있지만 파일, 함수 또는 코드 블록에서 한 번만 정의 할 수 있습니다.

변수가 맨 위에 선언되었지만 기본 함수 내에서 정의되고 초기화 된 다음 예제를 시도해보십시오.

#import <Foundation/Foundation.h>

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main () {
  /* variable definition: */
  int a, b;
  int c;
  float f;
 
  /* actual initialization */
  a = 10;
  b = 20;
  
  c = a + b;
  NSLog(@"value of c : %d \n", c);

  f = 70.0/3.0;
  NSLog(@"value of f : %f \n", f);
 
  return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-07 22:43:31.695 demo[14019] value of c : 30 
2013-09-07 22:43:31.695 demo[14019] value of f : 23.333334

동일한 개념이 선언시 함수 이름을 제공하고 실제 정의를 다른 곳에서 제공 할 수있는 함수 선언에도 적용됩니다. 다음 예제에서는 C 함수를 사용하여 설명했으며 Objective-C는 C 스타일 함수도 지원합니다.

// function declaration
int func();

int main() {
   // function call
   int i = func();
}

// function definition
int func() {
   return 0;
}

Objective-C의 Lvalue와 Rvalue

Objective-C에는 두 종류의 표현이 있습니다.

  • lvalue− 메모리 위치를 참조하는 표현식을 "lvalue"표현식이라고합니다. lvalue는 할당의 왼쪽 또는 오른쪽으로 나타날 수 있습니다.

  • rvalue− rvalue라는 용어는 메모리의 일부 주소에 저장된 데이터 값을 의미합니다. rvalue는 할당 된 값을 가질 수없는 표현식입니다. 이는 rvalue가 할당의 오른쪽에 나타날 수 있지만 왼쪽에는 나타나지 않을 수 있음을 의미합니다.

변수는 lvalue이므로 할당의 왼쪽에 나타날 수 있습니다. 숫자 리터럴은 r 값이므로 할당되지 않고 왼쪽에 표시되지 않을 수 있습니다. 다음은 유효한 진술입니다-

int g = 20;

그러나 다음은 유효한 문이 아니며 컴파일 타임 오류가 발생합니다.

10 = 20;

상수는 프로그램이 실행 중에 변경할 수없는 고정 값을 나타냅니다. 이러한 고정 값을literals.

상수는 정수 상수, 부동 상수, 문자 상수 또는 문자열 리터럴 과 같은 기본 데이터 유형 중 하나 일 수 있습니다 . 열거 형 상수도 있습니다.

그만큼 constants 정의 후에는 값을 수정할 수 없다는 점을 제외하면 일반 변수처럼 처리됩니다.

정수 리터럴

정수 리터럴은 10 진수, 8 진수 또는 16 진수 상수 일 수 있습니다. 접두사는 기수 또는 기수를 지정합니다. 16 진수는 0x 또는 0X, 8 진수는 0, 10 진수는 없습니다.

정수 리터럴은 각각 unsigned 및 long에 대해 U와 L의 조합 인 접미사를 가질 수도 있습니다. 접미사는 대문자 또는 소문자 일 수 있으며 순서에 관계없이 사용할 수 있습니다.

다음은 정수 리터럴의 몇 가지 예입니다.

212         /* Legal */
215u        /* Legal */
0xFeeL      /* Legal */
078         /* Illegal: 8 is not an octal digit */
032UU       /* Illegal: cannot repeat a suffix */

다음은 다양한 유형의 정수 리터럴의 다른 예입니다.

85         /* decimal */
0213       /* octal */
0x4b       /* hexadecimal */
30         /* int */
30u        /* unsigned int */
30l        /* long */
30ul       /* unsigned long */

부동 소수점 리터럴

부동 소수점 리터럴에는 정수 부분, 소수점, 소수 부분 및 지수 부분이 있습니다. 부동 소수점 리터럴을 10 진수 형식 또는 지수 형식으로 나타낼 수 있습니다.

소수 형식을 사용하여 표시하는 동안 소수점, 지수 또는 둘 다를 포함해야하며 지수 형식을 사용하여 표시하는 동안 정수 부분, 소수 부분 또는 둘 다를 포함해야합니다. 부호있는 지수는 e 또는 E로 도입됩니다.

다음은 부동 소수점 리터럴의 몇 가지 예입니다.

3.14159       /* Legal */
314159E-5L    /* Legal */
510E          /* Illegal: incomplete exponent */
210f          /* Illegal: no decimal or exponent */
.e55          /* Illegal: missing integer or fraction */

문자 상수

문자 리터럴은 작은 따옴표 (예 : 'x')로 묶여 있으며 다음과 같은 간단한 변수에 저장할 수 있습니다. char 유형.

문자 리터럴은 일반 문자 (예 : 'x'), 이스케이프 시퀀스 (예 : '\ t') 또는 범용 문자 (예 : '\ u02C0') 일 수 있습니다.

C에서 백 슬래시로 진행되는 특정 문자는 특별한 의미를 가지며 줄 바꿈 (\ n) 또는 탭 (\ t)과 같은 표현에 사용됩니다. 여기에 이러한 이스케이프 시퀀스 코드 목록이 있습니다.

탈출 시퀀스 의미
\\ \ 캐릭터
\ ' ' 캐릭터
\ " " 캐릭터
\? ? 캐릭터
\ㅏ 경고 또는 벨
\비 역행 키이
\에프 양식 피드
\엔 개행
\아르 자형 캐리지 리턴
\티 수평 탭
\V 수직 탭
\ ooo 1 ~ 3 자리의 8 진수
\ xhh. . . 하나 이상의 자릿수의 16 진수

다음은 몇 가지 이스케이프 시퀀스 문자를 보여주는 예입니다.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Hello\tWorld\n\n");
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-07 22:17:17.923 demo[17871] Hello	World

문자열 리터럴

문자열 리터럴 또는 상수는 큰 따옴표 ""로 묶여 있습니다. 문자열에는 일반 문자, 이스케이프 시퀀스 및 범용 문자와 같은 문자 리터럴과 유사한 문자가 포함됩니다.

문자열 리터럴을 사용하여 긴 줄을 여러 줄로 나누고 공백을 사용하여 구분할 수 있습니다.

다음은 문자열 리터럴의 몇 가지 예입니다. 세 가지 형식은 모두 동일한 문자열입니다.

"hello, dear"

"hello, \

dear"

"hello, " "d" "ear"

상수 정의

C에서 상수를 정의하는 두 가지 간단한 방법이 있습니다.

  • 사용 #define 전 처리기.

  • 사용 const 예어.

#define 전 처리기

다음은 상수를 정의하기 위해 #define 전처리기를 사용하는 양식입니다-

#define identifier value

다음 예제는 자세히 설명합니다-

#import <Foundation/Foundation.h>

#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'

int main() {
   int area;
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-07 22:18:16.637 demo[21460] value of area : 50
2013-09-07 22:18:16.638 demo[21460]

const 키워드

당신이 사용할 수있는 const 다음과 같이 특정 유형의 상수를 선언하는 접두사-

const type variable = value;

다음 예제는 자세히 설명합니다-

#import <Foundation/Foundation.h>

int main() {
   const int  LENGTH = 10;
   const int  WIDTH  = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-07 22:19:24.780 demo[25621] value of area : 50
2013-09-07 22:19:24.781 demo[25621]

CAPITALS에서 상수를 정의하는 것이 좋은 프로그래밍 방법입니다.

연산자는 컴파일러에게 특정 수학적 또는 논리적 조작을 수행하도록 지시하는 기호입니다. Objective-C 언어는 내장 연산자가 풍부하며 다음 유형의 연산자를 제공합니다.

  • 산술 연산자
  • 관계 연산자
  • 논리 연산자
  • 비트 연산자
  • 할당 연산자
  • 기타 연산자

이 튜토리얼은 산술, 관계형, 논리, 비트, 할당 및 기타 연산자를 하나씩 설명합니다.

산술 연산자

다음 표는 Objective-C 언어에서 지원하는 모든 산술 연산자를 보여줍니다. 변수 가정A 10 개와 가변 B 20 개를 보유하면-

예시보기

운영자 기술
+ 두 개의 피연산자를 더합니다. A + B는 30을 줄 것입니다
- 첫 번째에서 두 번째 피연산자를 뺍니다. A-B는 -10을 줄 것입니다.
* 두 피연산자를 곱합니다. A * B는 200을 줄 것입니다
/ 분자를 분모로 나눕니다. B / A는 2를 줄 것입니다
% 계수 연산자 및 정수 나누기 후의 나머지 B % A는 0을 제공합니다.
++ 증분 연산자는 정수 값을 1 씩 증가시킵니다. A ++는 11을 줄 것입니다
- 감소 연산자는 정수 값을 1 씩 감소시킵니다. A-- 9를 줄 것입니다

관계 연산자

다음 표는 Objective-C 언어에서 지원하는 모든 관계 연산자를 보여줍니다. 변수 가정A 10 개와 가변 B 20 개를 보유하면-

예시보기

운영자 기술
== 두 피연산자의 값이 같은지 확인합니다. 그렇다면 조건이 참이됩니다. (A == B)는 사실이 아닙니다.
! = 두 피연산자의 값이 같은지 확인합니다. 값이 같지 않으면 조건이 참이됩니다. (A! = B)는 사실입니다.
> 왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 큰지 확인합니다. 그렇다면 조건이 참이됩니다. (A> B)는 사실이 아닙니다.
< 왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 작은 지 확인합니다. 그렇다면 조건이 참이됩니다. (A <B)는 사실입니다.
> = 왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 크거나 같은지 확인합니다. 그렇다면 조건이 참이됩니다. (A> = B)는 사실이 아닙니다.
<= 왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 작거나 같은지 확인합니다. 그렇다면 조건이 참이됩니다. (A <= B)는 참입니다.

논리 연산자

다음 표는 Objective-C 언어에서 지원하는 모든 논리 연산자를 보여줍니다. 변수 가정A 1 및 변수 보유 B 0을 보유한 다음-

예시보기

운영자 기술
&& 논리 AND 연산자라고합니다. 두 피연산자가 모두 0이 아니면 조건이 참이됩니다. (A && B)는 거짓입니다.
|| 논리 OR 연산자라고합니다. 두 피연산자 중 하나가 0이 아니면 조건이 참이됩니다. (A || B) 사실입니다.
! 논리 NOT 연산자라고합니다. 피연산자의 논리 상태를 반전하는 데 사용합니다. 조건이 참이면 논리 NOT 연산자는 거짓으로 만듭니다. ! (A && B)는 참입니다.

비트 연산자

비트 연산자는 비트에서 작동하고 비트 단위로 작동합니다. &, |, ^의 진리표는 다음과 같습니다.

p & q p | 큐 피 ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

A = 60이라고 가정합니다. 그리고 B = 13; 이제 바이너리 형식으로 다음과 같이됩니다.

A = 0011 1100

B = 0000 1101

-----------------

A & B = 0000 1100

A | B = 0011 1101

A ^ B = 0011 0001

~ A = 1100 0011

Objective-C 언어에서 지원하는 Bitwise 연산자는 다음 표에 나열되어 있습니다. 변수 A가 60을 보유하고 변수 B가 13을 보유한다고 가정하면-

예시보기

운영자 기술
& 이진 AND 연산자는 두 피연산자에 모두있는 경우 결과에 비트를 복사합니다. (A & B)는 0000 1100 인 12를 줄 것입니다.
| 이진 OR 연산자는 피연산자 중 하나에 있으면 비트를 복사합니다. (A | B)는 61, 즉 0011 1101을 제공합니다.
^ 이진 XOR 연산자는 하나의 피연산자에만 설정되어 있지만 둘 다에 설정되지 않은 경우 비트를 복사합니다. (A ^ B)는 0011 0001 인 49를 제공합니다.
~ Binary Ones Complement Operator는 단항이며 비트를 '뒤집는'효과가 있습니다. (~ A)는 -61을 제공하며 2의 보수 형식으로 1100 0011입니다.
<< 이진 왼쪽 시프트 연산자. 왼쪽 피연산자 값은 오른쪽 피연산자에 지정된 비트 수만큼 왼쪽으로 이동합니다. << 2는 240, 즉 1111 0000을 제공합니다.
>> 이진 오른쪽 시프트 연산자. 왼쪽 피연산자 값은 오른쪽 피연산자에 지정된 비트 수만큼 오른쪽으로 이동합니다. A >> 2는 15, 즉 0000 1111을 제공합니다.

할당 연산자

Objective-C 언어에서 지원하는 할당 연산자는 다음과 같습니다.

예시보기

운영자 기술
= 단순 할당 연산자, 오른쪽 피연산자의 값을 왼쪽 피연산자로 할당합니다. C = A + B는 A + B의 값을 C에 할당합니다.
+ = AND 할당 연산자 추가, 왼쪽 피연산자에 오른쪽 피연산자를 추가하고 결과를 왼쪽 피연산자에 할당합니다. C + = A는 C = C + A와 같습니다.
-= AND 할당 연산자 빼기, 왼쪽 피연산자에서 오른쪽 피연산자를 빼고 결과를 왼쪽 피연산자에 할당합니다. C-= A는 C = C-A와 같습니다.
* = 곱하기 AND 할당 연산자, 오른쪽 피연산자와 왼쪽 피연산자를 곱하고 결과를 왼쪽 피연산자에 할당합니다. C * = A는 C = C * A와 같습니다.
/ = 나누기 AND 할당 연산자, 왼쪽 피연산자를 오른쪽 피연산자로 나누고 결과를 왼쪽 피연산자에 할당합니다. C / = A는 C = C / A와 같습니다.
% = 모듈러스 AND 할당 연산자, 두 개의 피연산자를 사용하여 모듈러스를 취하고 결과를 왼쪽 피연산자에 할당합니다. C % = A는 C = C % A와 동일합니다.
<< = 왼쪽 시프트 AND 할당 연산자 C << = 2는 C = C << 2와 동일합니다.
>> = 오른쪽 시프트 AND 할당 연산자 C >> = 2는 C = C >> 2와 동일합니다.
& = 비트 AND 할당 연산자 C & = 2는 C = C & 2와 동일합니다.
^ = 비트 배타적 OR 및 할당 연산자 C ^ = 2는 C = C ^ 2와 같습니다.
| = 비트 포함 OR 및 할당 연산자 C | = 2는 C = C | 2

기타 연산자 ↦ sizeof & 삼항

다음을 포함한 다른 중요한 연산자는 거의 없습니다. sizeof? : Objective-C 언어에서 지원합니다.

예시보기

운영자 기술
sizeof () 변수의 크기를 반환합니다. a가 정수인 sizeof (a)는 4를 반환합니다.
& 변수의 주소를 반환합니다. &ㅏ; 변수의 실제 주소를 제공합니다.
* 변수에 대한 포인터. *ㅏ; 변수를 가리 킵니다.
? : 조건식 조건이 참이면? 그런 다음 값 X : 그렇지 않으면 값 Y

Objective-C의 연산자 우선 순위

연산자 우선 순위는 식의 용어 그룹화를 결정합니다. 이는식이 평가되는 방식에 영향을줍니다. 특정 연산자는 다른 연산자보다 우선 순위가 높습니다. 예를 들어 곱셈 연산자는 더하기 연산자보다 우선 순위가 높습니다.

예를 들어, x = 7 + 3 * 2; 여기서 x는 연산자 *가 +보다 우선 순위가 높기 때문에 20이 아닌 13이 할당됩니다. 따라서 먼저 3 * 2를 곱한 다음 7에 더합니다.

여기에서 우선 순위가 가장 높은 연산자는 테이블 맨 위에 표시되고 가장 낮은 연산자는 맨 아래에 표시됩니다. 식 내에서 우선 순위가 높은 연산자가 먼저 평가됩니다.

범주  운영자  연관성 
접미사  () []->. ++--   좌에서 우로 
단항  +-! ~ ++--(유형) * & sizeof  오른쪽에서 왼쪽으로 
곱셈   * / %  좌에서 우로 
첨가물   +-  좌에서 우로 
시프트   << >>  좌에서 우로 
관계형   <<=>> =  좌에서 우로 
평등   ==! =  좌에서 우로 
비트 XOR  좌에서 우로 
비트 OR  좌에서 우로 
논리적 AND  &&  좌에서 우로 
논리적 OR  ||  좌에서 우로 
가정 어구  ? :  오른쪽에서 왼쪽으로 
할당  = + =-= * = / = % = >> = << = & = ^ = | =  오른쪽에서 왼쪽으로 
반점  좌에서 우로 

코드 블록을 여러 번 실행해야하는 상황이있을 수 있습니다. 일반적으로 명령문은 순차적으로 실행됩니다. 함수의 첫 번째 명령문이 먼저 실행되고 두 번째 명령문이 실행되는 식입니다.

프로그래밍 언어는보다 복잡한 실행 경로를 허용하는 다양한 제어 구조를 제공합니다.

루프 문을 사용하면 문 또는 문 그룹을 여러 번 실행할 수 있으며 다음은 대부분의 프로그래밍 언어에서 루프 문의 일반적인 형식입니다.

Objective-C 프로그래밍 언어는 루핑 요구 사항을 처리하기 위해 다음 유형의 루프를 제공합니다. 자세한 내용을 확인하려면 다음 링크를 클릭하십시오.

Sr. 아니. 루프 유형 및 설명
1 while 루프

주어진 조건이 참인 동안 명령문 또는 명령문 그룹을 반복합니다. 루프 본문을 실행하기 전에 조건을 테스트합니다.

2 for 루프

일련의 문을 여러 번 실행하고 루프 변수를 관리하는 코드를 축약합니다.

do ... while 루프

while 문과 비슷하지만 루프 본문의 끝에서 조건을 테스트한다는 점이 다릅니다.

4 중첩 된 루프

while, for 또는 do..while 루프 내에서 하나 이상의 루프를 사용할 수 있습니다.

루프 제어문

루프 제어문은 정상적인 순서에서 실행을 변경합니다. 실행이 범위를 벗어나면 해당 범위에서 생성 된 모든 자동 개체가 삭제됩니다.

Objective-C는 다음 제어문을 지원합니다. 자세한 내용을 확인하려면 다음 링크를 클릭하십시오.

Sr. 아니. 제어문 및 설명
1 break 문

종료 loop 또는 switch 문을 열고 루프 또는 스위치 바로 다음 문으로 실행을 전송합니다.

2 계속 진술

루프가 본문의 나머지 부분을 건너 뛰고 반복하기 전에 즉시 상태를 다시 테스트하도록합니다.

무한 루프

조건이 거짓이되지 않으면 루프는 무한 루프가됩니다. 그만큼for루프는 전통적으로 이러한 목적으로 사용됩니다. for 루프를 구성하는 세 가지 표현식이 필요하지 않기 때문에 조건식을 비워 두어 무한 루프를 만들 수 있습니다.

#import <Foundation/Foundation.h>
 
int main () {

   for( ; ; ) {
      NSLog(@"This loop will run forever.\n");
   }

   return 0;
}

조건식이 없으면 참으로 간주됩니다. 초기화 및 증분 표현식이있을 수 있지만 Objective-C 프로그래머는 더 일반적으로 for (;;) 구문을 사용하여 무한 루프를 나타냅니다.

의사 결정 구조에서는 프로그래머가 조건이 참인 경우 실행될 명령문 또는 명령문과 함께 프로그램에서 평가하거나 테스트 할 하나 이상의 조건을 지정하고, 조건이 충족되는 경우 실행될 다른 명령문을 선택적으로 지정해야합니다. 거짓으로 결정됩니다.

다음은 대부분의 프로그래밍 언어에서 발견되는 일반적인 의사 결정 구조의 일반적인 형태입니다.

Objective-C 프로그래밍 언어는 non-zeronon-nulltrue, 그리고 둘 중 하나 인 경우 zero 또는 null이면 다음과 같이 가정합니다. false 값.

Objective-C 프로그래밍 언어는 다음 유형의 의사 결정 문을 제공합니다. 자세한 내용을 확인하려면 다음 링크를 클릭하십시오-

Sr. 아니. 성명 및 설명
1 if 문

if statement 부울 표현식과 하나 이상의 문으로 구성됩니다.

2 if ... else 문

if statement 뒤에 선택 사항이 올 수 있습니다. else statement, 부울 표현식이 false 일 때 실행됩니다.

중첩 된 if 문

하나를 사용할 수 있습니다 if 또는 else if 다른 내부의 진술 if 또는 else if 진술 (들).

4 switch 문

switch 문을 사용하면 변수가 값 목록과 같은지 테스트 할 수 있습니다.

5 중첩 된 switch 문

하나를 사용할 수 있습니다 switch 다른 내부의 진술 switch 진술 (들).

? : 운영자

우리는 conditional operator ? : 대체하는 데 사용할 수있는 이전 장에서 if...else진술. 그것은 다음과 같은 일반적인 형태를 가지고 있습니다-

Exp1 ? Exp2 : Exp3;

Exp1, Exp2 및 Exp3은 표현식입니다. 콜론의 사용과 배치에 주목하십시오.

값은? 식은 다음과 같이 결정됩니다. Exp1이 평가됩니다. 참이면 Exp2가 평가되고 전체?의 값이됩니다. 표현. Exp1이 false이면 Exp3이 평가되고 해당 값이 표현식의 값이됩니다.

함수는 함께 작업을 수행하는 문 그룹입니다. 모든 Objective-C 프로그램에는 하나의 C 함수가 있습니다.main(), 가장 사소한 프로그램은 모두 추가 기능을 정의 할 수 있습니다.

코드를 별도의 함수로 나눌 수 있습니다. 코드를 다른 함수로 나누는 방법은 사용자에게 달려 있지만 논리적으로 나누는 것은 일반적으로 각 함수가 특정 작업을 수행하는 것입니다.

기능 declaration함수의 이름, 반환 유형 및 매개 변수에 대해 컴파일러에 알려줍니다. 기능definition 함수의 실제 본문을 제공합니다.

기본적으로 Objective-C에서는 함수를 메서드로 호출합니다.

Objective-C 기반 프레임 워크는 프로그램에서 호출 할 수있는 다양한 기본 제공 메서드를 제공합니다. 예 : 방법appendString() 다른 문자열에 문자열을 추가합니다.

메서드는 함수 나 서브 루틴, 프로 시저 등과 같은 다양한 이름으로 알려져 있습니다.

방법 정의

Objective-C 프로그래밍 언어에서 메서드 정의의 일반적인 형식은 다음과 같습니다.

- (return_type) method_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen {
   body of the function
}

Objective-C 프로그래밍 언어의 메서드 정의는 메서드 헤더메서드 본문으로 구성 됩니다. 다음은 방법의 모든 부분입니다.

  • Return Type− 메서드는 값을 반환 할 수 있습니다. 그만큼return_type함수가 반환하는 값의 데이터 유형입니다. 일부 메서드는 값을 반환하지 않고 원하는 작업을 수행합니다. 이 경우 return_type은 키워드입니다.void.

  • Method Name− 이것은 분석법의 실제 이름입니다. 메소드 이름과 매개 변수 목록은 함께 메소드 서명을 구성합니다.

  • Arguments− 인수는 자리 표시 자와 같습니다. 함수가 호출되면 인수에 값을 전달합니다. 이 값을 실제 매개 변수 또는 인수라고합니다. 매개 변수 목록은 메소드 인수의 유형, 순서 및 수를 참조합니다. 인수는 선택 사항입니다. 즉, 메서드에 인수가 없을 수 있습니다.

  • Joining Argument − 결합 주장은 읽기 쉽게 만들고 호출하는 동안 명확하게 만드는 것입니다.

  • Method Body − 메소드 본문에는 메소드의 기능을 정의하는 명령문 모음이 포함되어 있습니다.

다음은 호출 된 메소드의 소스 코드입니다. max(). 이 메서드는 두 개의 매개 변수 num1과 num2를 취하고 둘 사이의 최대 값을 반환합니다.

/* function returning the max between two numbers */
- (int) max:(int) num1 secondNumber:(int) num2 {
   
   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

메서드 선언

방법 declaration컴파일러에게 함수 이름과 메서드 호출 방법을 알려줍니다. 함수의 실제 본문은 별도로 정의 할 수 있습니다.

메서드 선언은 다음과 같은 부분으로 구성됩니다.

- (return_type) function_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen;

위에 정의 된 함수 max ()의 경우 다음은 메소드 선언입니다.

-(int) max:(int)num1 andNum2:(int)num2;

한 소스 파일에서 메소드를 정의하고 다른 파일에서 해당 메소드를 호출 할 때 메소드 선언이 필요합니다. 이 경우 함수를 호출하는 파일의 맨 위에 함수를 선언해야합니다.

메서드 호출

Objective-C 메서드를 만드는 동안 함수가 수행해야하는 작업에 대한 정의를 제공합니다. 메서드를 사용하려면 정의 된 작업을 수행하기 위해 해당 함수를 호출해야합니다.

프로그램이 함수를 호출하면 프로그램 제어가 호출 된 메소드로 전송됩니다. 호출 된 메서드는 정의 된 작업을 수행하고 return 문이 실행되거나 함수 종료 중괄호에 도달하면 프로그램 제어를 다시 기본 프로그램으로 반환합니다.

메서드를 호출하려면 메서드 이름과 함께 필요한 매개 변수를 전달하기 만하면됩니다. 메서드가 값을 반환하면 반환 된 값을 저장할 수 있습니다. 예를 들면-

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
/* method declaration */
- (int)max:(int)num1 andNum2:(int)num2;
@end

@implementation SampleClass

/* method returning the max between two numbers */
- (int)max:(int)num1 andNum2:(int)num2 {

   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

@end

int main () {
   
   /* local variable definition */
   int a = 100;
   int b = 200;
   int ret;
   
   SampleClass *sampleClass = [[SampleClass alloc]init];

   /* calling a method to get max value */
   ret = [sampleClass max:a andNum2:b];
 
   NSLog(@"Max value is : %d\n", ret );
   return 0;
}

main () 함수와 함께 max () 함수를 유지하고 소스 코드를 준수했습니다. 최종 실행 파일을 실행하는 동안 다음 결과가 생성됩니다.

2013-09-07 22:28:45.912 demo[26080] Max value is : 200

함수 인수

함수가 인수를 사용하려면 인수 값을 허용하는 변수를 선언해야합니다. 이러한 변수를formal parameters 기능의.

형식 매개 변수는 함수 내부의 다른 지역 변수처럼 작동하며 함수에 들어가면 생성되고 종료시 삭제됩니다.

함수를 호출하는 동안 인수를 함수에 전달할 수있는 두 가지 방법이 있습니다.

Sr. 아니. 통화 유형 및 설명
1 가치로 부르기

이 메서드는 인수의 실제 값을 함수의 형식 매개 변수에 복사합니다. 이 경우 함수 내에서 매개 변수를 변경해도 인수에 영향을주지 않습니다.

2 참조로 전화

이 메서드는 인수의 주소를 형식 매개 변수에 복사합니다. 함수 내에서 주소는 호출에 사용 된 실제 인수에 액세스하는 데 사용됩니다. 이는 매개 변수의 변경 사항이 인수에 영향을 미친다는 것을 의미합니다.

기본적으로 Objective-C는 call by value인수를 전달합니다. 일반적으로 이는 함수 내의 코드가 함수를 호출하는 데 사용되는 인수를 변경할 수 없음을 의미하며, 위에서 언급 한 max () 함수를 호출하는 동안 동일한 메서드를 사용했습니다.

Objective-C 클래스는 데이터를 관련 동작과 결합하는 객체를 정의합니다. 때로는 메서드 모음이 아닌 단일 작업 또는 동작 단위를 나타내는 것이 합리적입니다.

블록은 C, Objective-C 및 C ++에 추가 된 언어 수준 기능으로, 마치 값인 것처럼 메서드 또는 함수에 전달할 수있는 고유 한 코드 세그먼트를 만들 수 있습니다. 블록은 Objective-C 객체이므로 NSArray 또는 NSDictionary와 같은 컬렉션에 추가 할 수 있습니다. 또한 둘러싸는 범위에서 값을 캡처하여 다른 프로그래밍 언어의 클로저 또는 람다와 유사하게 만들 수 있습니다.

간단한 블록 선언 구문

returntype (^blockName)(argumentType);

간단한 블록 구현

returntype (^blockName)(argumentType)= ^{
};

다음은 간단한 예입니다.

void (^simpleBlock)(void) = ^{
   NSLog(@"This is a block");
};

다음을 사용하여 블록을 호출 할 수 있습니다.

simpleBlock();

블록은 인수를 취하고 값을 반환합니다.

블록은 메소드 및 함수와 마찬가지로 인수를 취하고 값을 반환 할 수도 있습니다.

다음은 인수와 반환 값으로 블록을 구현하고 호출하는 간단한 예제입니다.

double (^multiplyTwoValues)(double, double) = 
   ^(double firstValue, double secondValue) {
      return firstValue * secondValue;
   };

double result = multiplyTwoValues(2,4); 
NSLog(@"The result is %f", result);

유형 정의를 사용하는 블록

다음은 블록에서 typedef를 사용하는 간단한 예입니다. 이 샘플을 참고하십시오doesn't workonline compiler지금은. 사용하다XCode 동일하게 실행합니다.

#import <Foundation/Foundation.h>

typedef void (^CompletionBlock)();
@interface SampleClass:NSObject
- (void)performActionWithCompletion:(CompletionBlock)completionBlock;
@end

@implementation SampleClass

- (void)performActionWithCompletion:(CompletionBlock)completionBlock {

   NSLog(@"Action Performed");
   completionBlock();
}

@end

int main() {
   
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass performActionWithCompletion:^{
      NSLog(@"Completion is called to intimate action is performed.");
   }];

   return 0;
}

컴파일하고 실행하면 다음 결과가 생성됩니다.

2013-09-10 08:13:57.155 demo[284:303] Action Performed
2013-09-10 08:13:57.157 demo[284:303] Completion is called to intimate action is performed.

블록은 iOS 애플리케이션과 Mac OS X에서 더 많이 사용됩니다. 따라서 블록 사용을 이해하는 것이 더 중요합니다.

Objective-C 프로그래밍 언어에서 int, float, bool과 같은 기본 데이터 유형을 객체 형태로 저장하기 위해

Objective-C는 NSNumber로 작업 할 수있는 다양한 방법을 제공하며 중요한 방법은 다음 표에 나열되어 있습니다.

Sr. 아니. 방법 및 설명
1

+ (NSNumber *)numberWithBool:(BOOL)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하여 BOOL로 취급합니다.

2

+ (NSNumber *)numberWithChar:(char)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하며이를 부호있는 문자로 취급합니다.

+ (NSNumber *)numberWithDouble:(double)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하여 double로 처리합니다.

4

+ (NSNumber *)numberWithFloat:(float)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하여 float로 취급합니다.

5

+ (NSNumber *)numberWithInt:(int)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하여이를 부호있는 정수로 취급합니다.

6

+ (NSNumber *)numberWithInteger:(NSInteger)value

주어진 값을 포함하는 NSNumber 객체를 생성하고 반환하여 NSInteger로 취급합니다.

7

- (BOOL)boolValue

수신자의 값을 BOOL로 반환합니다.

8

- (char)charValue

수신자의 값을 문자로 반환합니다.

9

- (double)doubleValue

수신자의 값을 double로 반환합니다.

10

- (float)floatValue

수신자의 값을 float로 반환합니다.

11

- (NSInteger)integerValue

수신자의 값을 NSInteger로 반환합니다.

12

- (int)intValue

수신자의 값을 int로 반환합니다.

13

- (NSString *)stringValue

수신자의 값을 사람이 읽을 수있는 문자열로 반환합니다.

다음은 두 숫자를 곱하고 제품을 반환하는 NSNumber를 사용하는 간단한 예입니다.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b;
@end

@implementation SampleClass

- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b {
   float number1 = [a floatValue];
   float number2 = [b floatValue];
   float product = number1 * number2;
   NSNumber *result = [NSNumber numberWithFloat:product];
   return result;
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   SampleClass *sampleClass = [[SampleClass alloc]init];
   NSNumber *a = [NSNumber numberWithFloat:10.5];
   NSNumber *b = [NSNumber numberWithFloat:10.0];   
   NSNumber *result = [sampleClass multiplyA:a withB:b];
   NSString *resultString = [result stringValue];
   NSLog(@"The product is %@",resultString);

   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-14 18:53:40.575 demo[16787] The product is 105

Objective-C 프로그래밍 언어는 다음과 같은 데이터 구조를 제공합니다. the array, 동일한 유형의 요소의 고정 크기 순차 컬렉션을 저장할 수 있습니다. 배열은 데이터 모음을 저장하는 데 사용되지만 배열을 동일한 유형의 변수 모음으로 생각하는 것이 더 유용합니다.

number0, number1, ..., number99와 같은 개별 변수를 선언하는 대신 숫자와 같은 하나의 배열 변수를 선언하고 numbers [0], numbers [1] 및 ..., numbers [99]를 사용하여 개별 변수. 배열의 특정 요소는 인덱스로 액세스됩니다.

모든 어레이는 연속적인 메모리 위치로 구성됩니다. 가장 낮은 주소는 첫 번째 요소에 해당하고 가장 높은 주소는 마지막 요소에 해당합니다.

배열 선언

Objective-C에서 배열을 선언하기 위해 프로그래머는 다음과 같이 배열에 필요한 요소의 유형과 요소의 수를 지정합니다.

type arrayName [ arraySize ];

이것을 1 차원 배열 이라고합니다 . 그만큼arraySize 0보다 큰 정수 상수 여야하며 type유효한 Objective-C 데이터 유형이 될 수 있습니다. 예를 들어, 10 개의 요소 배열을 선언하려면balance double 유형의 경우 다음 문을 사용하십시오.

double balance[10];

이제 balance 는 최대 10 개의 이중 숫자를 보유하기에 충분한 가변 배열입니다.

배열 초기화

Objective-C에서 배열을 하나씩 또는 다음과 같이 단일 문을 사용하여 초기화 할 수 있습니다.

double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};

중괄호 {} 사이의 값 수는 대괄호 [] 사이의 배열에 대해 선언 한 요소 수보다 클 수 없습니다. 다음은 배열의 단일 요소를 할당하는 예입니다.

배열의 크기를 생략하면 초기화를 저장할 수있을만큼 큰 배열이 생성됩니다. 따라서 다음과 같이 쓰면-

double balance[] = {1000.0, 2.0, 3.4, 17.0, 50.0};

이전 예제에서했던 것과 똑같은 배열을 만들 것입니다.

balance[4] = 50.0;

위의 명령문은 배열의 요소 번호 5에 50.0 값을 할당합니다. 모든 배열은 기본 인덱스라고도하는 첫 번째 요소의 인덱스로 0을 갖기 때문에 4 번째 인덱스가있는 배열은 5 번째, 즉 마지막 요소가됩니다. 다음은 위에서 논의한 동일한 배열의 그림 표현입니다.

배열 요소에 액세스

배열 이름을 인덱싱하여 요소에 액세스합니다. 이는 배열 이름 뒤에 대괄호 안에 요소의 인덱스를 배치하여 수행됩니다. 예를 들면-

double salary = balance[9];

위의 문은 배열에서 10 번째 요소를 가져와 급여 변수에 값을 할당합니다. 다음은 위에서 언급 한 세 가지 개념을 모두 사용하는 예입니다. 선언, 할당 및 액세스 배열-

#import <Foundation/Foundation.h>
 
int main () {
   int n[ 10 ];   /* n is an array of 10 integers */
   int i,j;
 
   /* initialize elements of array n to 0 */         
   for ( i = 0; i < 10; i++ ) {
      n[ i ] = i + 100;    /* set element at location i to i + 100 */
   }
   
   /* output each array element's value */
   for (j = 0; j < 10; j++ ) {
      NSLog(@"Element[%d] = %d\n", j, n[j] );
   }
 
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 01:24:06.669 demo[16508] Element[0] = 100
2013-09-14 01:24:06.669 demo[16508] Element[1] = 101
2013-09-14 01:24:06.669 demo[16508] Element[2] = 102
2013-09-14 01:24:06.669 demo[16508] Element[3] = 103
2013-09-14 01:24:06.669 demo[16508] Element[4] = 104
2013-09-14 01:24:06.669 demo[16508] Element[5] = 105
2013-09-14 01:24:06.669 demo[16508] Element[6] = 106
2013-09-14 01:24:06.669 demo[16508] Element[7] = 107
2013-09-14 01:24:06.669 demo[16508] Element[8] = 108
2013-09-14 01:24:06.669 demo[16508] Element[9] = 109

Objective-C 배열 세부 정보

배열은 Objective-C에 중요하며 더 많은 세부 정보가 필요합니다. Objective-C 프로그래머에게 명확해야 할 배열과 관련된 몇 가지 중요한 개념이 있습니다.

Sr. 아니. 개념 및 설명
1 다차원 배열

Objective-C는 다차원 배열을 지원합니다. 다차원 배열의 가장 간단한 형태는 2 차원 배열입니다.

2 함수에 배열 전달

인덱스없이 배열의 이름을 지정하여 배열에 대한 포인터를 함수에 전달할 수 있습니다.

함수에서 배열 반환

Objective-C를 사용하면 함수가 배열을 반환 할 수 있습니다.

4 배열에 대한 포인터

인덱스없이 배열 이름을 지정하여 배열의 첫 번째 요소에 대한 포인터를 생성 할 수 있습니다.

Objective-C의 포인터는 쉽고 재미있게 배울 수 있습니다. 일부 Objective-C 프로그래밍 작업은 포인터를 사용하여 더 쉽게 수행되며 동적 메모리 할당과 같은 다른 작업은 포인터를 사용하지 않고 수행 할 수 없습니다. 따라서 완벽한 Objective-C 프로그래머가되기 위해서는 포인터를 배울 필요가 있습니다. 간단하고 쉬운 단계로 학습을 시작하겠습니다.

아시다시피 모든 변수는 메모리 위치이며 모든 메모리 위치에는 메모리의 주소를 나타내는 앰퍼샌드 (&) 연산자를 사용하여 액세스 할 수있는 주소가 정의되어 있습니다. 정의 된 변수의 주소를 인쇄 할 다음 예제를 고려하십시오.

#import <Foundation/Foundation.h>

int main () {
   int  var1;
   char var2[10];

   NSLog(@"Address of var1 variable: %x\n", &var1 );
   NSLog(@"Address of var2 variable: %x\n", &var2 );

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-13 03:18:45.727 demo[17552] Address of var1 variable: 1c0843fc
2013-09-13 03:18:45.728 demo[17552] Address of var2 variable: 1c0843f0

그래서 당신은 메모리 주소가 무엇이며 어떻게 접근하는지 이해 했으므로 개념의 기초는 끝났습니다. 이제 포인터가 무엇인지 살펴 보겠습니다.

포인터 란?

pointer다른 변수의 주소, 즉 메모리 위치의 직접 주소 인 변수입니다. 다른 변수 나 상수와 마찬가지로 포인터를 사용하여 변수 주소를 저장하려면 먼저 포인터를 선언해야합니다. 포인터 변수 선언의 일반적인 형식은 다음과 같습니다.

type *var-name;

여기, type포인터의 기본 유형입니다. 유효한 Objective-C 데이터 유형이어야하며var-name포인터 변수의 이름입니다. 포인터를 선언하는 데 사용한 별표 *는 곱하기에 사용하는 것과 동일한 별표입니다. 그러나이 명령문에서 별표는 변수를 포인터로 지정하는 데 사용됩니다. 다음은 유효한 포인터 선언입니다-

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

정수, 부동 소수점, 문자 등 모든 포인터 값의 실제 데이터 유형은 메모리 주소를 나타내는 긴 16 진수와 동일합니다. 데이터 유형이 다른 포인터 간의 유일한 차이점은 포인터가 가리키는 변수 또는 상수의 데이터 유형입니다.

포인터는 어떻게 사용하나요?

포인터의 도움으로 매우 자주 수행 할 중요한 작업은 거의 없습니다. (a) 포인터 변수를 정의합니다. (b) 변수의 주소를 포인터에 할당하고 (c)마지막으로 포인터 변수에서 사용 가능한 주소의 값에 액세스합니다. 이것은 단항 연산자를 사용하여 수행됩니다.*피연산자가 지정한 주소에있는 변수의 값을 반환합니다. 다음 예제는 이러한 작업을 사용합니다-

#import <Foundation/Foundation.h>

int main () {
   int  var = 20;    /* actual variable declaration */
   int  *ip;         /* pointer variable declaration */  
   ip = &var;       /* store address of var in pointer variable*/

   NSLog(@"Address of var variable: %x\n", &var  );

   /* address stored in pointer variable */
   NSLog(@"Address stored in ip variable: %x\n", ip );

   /* access the value using the pointer */
   NSLog(@"Value of *ip variable: %d\n", *ip );

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-13 03:20:21.873 demo[24179] Address of var variable: 337ed41c
2013-09-13 03:20:21.873 demo[24179] Address stored in ip variable: 337ed41c
2013-09-13 03:20:21.874 demo[24179] Value of *ip variable: 20

Objective-C의 NULL 포인터

할당 할 정확한 주소가없는 경우 항상 NULL 값을 포인터 변수에 할당하는 것이 좋습니다. 이것은 변수 선언시 수행됩니다. NULL이 할당 된 포인터를null 바늘.

NULL 포인터는 여러 표준 라이브러리에 정의 된 값이 0 인 상수입니다. 다음 프로그램을 고려하십시오-

#import <Foundation/Foundation.h>

int main () {
   int  *ptr = NULL;
   NSLog(@"The value of ptr is : %x\n", ptr  );
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-13 03:21:19.447 demo[28027] The value of ptr is : 0

대부분의 운영 체제에서는 해당 메모리가 운영 체제에 의해 예약되어 있기 때문에 프로그램이 주소 0의 메모리에 액세스 할 수 없습니다. 그러나 메모리 주소 0은 특별한 의미가 있습니다. 포인터가 액세스 가능한 메모리 위치를 가리 키도록 의도되지 않았 음을 나타냅니다. 그러나 관례 상 포인터에 null (영) 값이 포함되어 있으면 아무것도 가리키는 것으로 간주되지 않습니다.

널 포인터를 확인하려면 다음과 같이 if 문을 사용할 수 있습니다.

if(ptr)     /* succeeds if p is not null */
if(!ptr)    /* succeeds if p is null */

Objective-C 포인터 상세

포인터는 많지만 쉬운 개념을 가지고 있으며 Objective-C 프로그래밍에 매우 중요합니다. Objective-C 프로그래머에게 분명해야 할 몇 가지 중요한 포인터 개념이 있습니다.

Sr. 아니. 개념 및 설명
1 Objective-C-포인터 산술

포인터에 사용할 수있는 산술 연산자는 ++,-, +,-네 가지입니다.

2 Objective-C-포인터 배열

여러 포인터를 보유하도록 배열을 정의 할 수 있습니다.

Objective-C-포인터에 대한 포인터

Objective-C를 사용하면 포인터에 포인터를 둘 수 있습니다.

4 Objective-C의 함수에 대한 포인터 전달

참조 또는 주소로 인수를 전달하면 호출 된 함수에서 전달 된 인수를 호출 함수에서 변경할 수 있습니다.

5 Objective-C의 함수에서 포인터 반환

Objective-C는 함수가 지역 변수, 정적 변수 및 동적으로 할당 된 메모리에 대한 포인터를 반환 할 수 있도록합니다.

Objective-C 프로그래밍 언어의 문자열은 NSString을 사용하여 표현되며 하위 클래스 NSMutableString은 문자열 객체를 생성하는 여러 방법을 제공합니다. 문자열 객체를 생성하는 가장 간단한 방법은 Objective-C @ "..."구문을 사용하는 것입니다.

NSString *greeting = @"Hello";

문자열을 만들고 인쇄하는 간단한 예가 아래에 나와 있습니다.

#import <Foundation/Foundation.h>

int main () {
   NSString *greeting = @"Hello";
   NSLog(@"Greeting message: %@\n", greeting );

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-11 01:21:39.922 demo[23926] Greeting message: Hello

Objective-C는 문자열 조작을위한 다양한 방법을 지원합니다.

Sr. 아니. 방법 및 목적
1

- (NSString *)capitalizedString;

수신자의 대문자 표현을 반환합니다.

2

- (unichar)characterAtIndex:(NSUInteger)index;

주어진 배열 위치에있는 문자를 반환합니다.

- (double)doubleValue;

수신자 텍스트의 부동 소수점 값을 double로 반환합니다.

4

- (float)floatValue;

수신자 텍스트의 부동 소수점 값을 부동 소수점으로 반환합니다.

5

- (BOOL)hasPrefix:(NSString *)aString;

주어진 문자열이 수신자의 시작 문자와 일치하는지 여부를 나타내는 부울 값을 리턴합니다.

6

- (BOOL)hasSuffix:(NSString *)aString;

주어진 문자열이 수신자의 종료 문자와 일치하는지 여부를 나타내는 부울 값을 리턴합니다.

7

- (id)initWithFormat:(NSString *)format ...;

주어진 형식 문자열을 나머지 인수 값이 대체되는 템플릿으로 사용하여 초기화 된 NSString 개체를 반환합니다.

8

- (NSInteger)integerValue;

수신자 텍스트의 NSInteger 값을 반환합니다.

9

- (BOOL)isEqualToString:(NSString *)aString;

주어진 문자열이 리터럴 유니 코드 기반 비교를 사용하여 수신자와 같은지 여부를 나타내는 부울 값을 리턴합니다.

10

- (NSUInteger)length;

수신자의 유니 코드 문자 수를 반환합니다.

11

- (NSString *)lowercaseString;

수신자의 소문자 표현을 반환합니다.

12

- (NSRange)rangeOfString:(NSString *)aString;

수신자 내에서 주어진 문자열이 처음 나타나는 범위를 찾아 반환합니다.

13

- (NSString *)stringByAppendingFormat:(NSString *)format ...;

주어진 형식 문자열과 다음 인수로 구성된 문자열을 수신자에 추가하여 만든 문자열을 반환합니다.

14

- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;

주어진 문자 집합에 포함 된 수신자 문자의 양쪽 끝에서 제거하여 만든 새 문자열을 반환합니다.

15

- (NSString *)substringFromIndex:(NSUInteger)anIndex;

지정된 인덱스의 문자부터 끝까지 수신자의 문자를 포함하는 새 문자열을 반환합니다.

다음 예제는 위에서 언급 한 기능을 거의 사용하지 않습니다.

#import <Foundation/Foundation.h>

int main () {
   NSString *str1 = @"Hello";
   NSString *str2 = @"World";
   NSString *str3;
   int  len ;

   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   /* uppercase string */
   str3 = [str2 uppercaseString];
   NSLog(@"Uppercase String :  %@\n", str3 );

   /* concatenates str1 and str2 */
   str3 = [str1 stringByAppendingFormat:@"World"];
   NSLog(@"Concatenated string:   %@\n", str3 );

   /* total length of str3 after concatenation */
   len = [str3 length];
   NSLog(@"Length of Str3 :  %d\n", len );

   /* InitWithFormat */
   str3 = [[NSString alloc] initWithFormat:@"%@ %@",str1,str2];	
   NSLog(@"Using initWithFormat:   %@\n", str3 );
   [pool drain];

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-11 01:15:45.069 demo[30378] Uppercase String :  WORLD
2013-09-11 01:15:45.070 demo[30378] Concatenated string:   HelloWorld
2013-09-11 01:15:45.070 demo[30378] Length of Str3 :  10
2013-09-11 01:15:45.070 demo[30378] Using initWithFormat:   Hello World

Objective-C NSString 관련 메서드의 전체 목록은 NSString Class Reference 에서 찾을 수 있습니다 .

Objective-C 배열을 사용하면 동일한 종류의 여러 데이터 항목을 보유 할 수있는 변수 유형을 정의 할 수 있습니다. structure Objective-C 프로그래밍에서 사용할 수있는 또 다른 사용자 정의 데이터 유형으로 다른 종류의 데이터 항목을 결합 할 수 있습니다.

구조는 기록을 나타내는 데 사용됩니다. 도서관에서 책을 추적하고 싶다고 가정 해 보겠습니다. 각 책에 대한 다음 속성을 추적 할 수 있습니다.

  • Title
  • Author
  • Subject
  • 도서 ID

구조 정의

구조를 정의하려면 다음을 사용해야합니다. struct성명서. struct 문은 프로그램에 대해 둘 이상의 멤버를 사용하여 새 데이터 유형을 정의합니다. struct 문의 형식은 다음과 같습니다.

struct [structure tag] {
   member definition;
   member definition;
   ...
   member definition;
} [one or more structure variables];

그만큼 structure tag선택적이며 각 멤버 정의는 int i와 같은 일반 변수 정의입니다. 또는 float f; 또는 다른 유효한 변수 정의. 구조 정의의 끝에서 마지막 세미콜론 앞에 하나 이상의 구조 변수를 지정할 수 있지만 선택 사항입니다. 다음은 Book 구조를 선언하는 방법입니다.

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
} book;

구조 멤버 액세스

구조의 구성원에 액세스하려면 member access operator (.). 멤버 액세스 연산자는 구조 변수 이름과 액세스하려는 구조 멤버 사이의 마침표로 코딩됩니다. 당신은 사용할 것입니다struct구조 유형의 변수를 정의하는 키워드입니다. 다음은 구조의 사용법을 설명하는 예입니다-

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};
 
int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   /* print Book1 info */
   NSLog(@"Book 1 title : %@\n", Book1.title);
   NSLog(@"Book 1 author : %@\n", Book1.author);
   NSLog(@"Book 1 subject : %@\n", Book1.subject);
   NSLog(@"Book 1 book_id : %d\n", Book1.book_id);

   /* print Book2 info */
   NSLog(@"Book 2 title : %@\n", Book2.title);
   NSLog(@"Book 2 author : %@\n", Book2.author);
   NSLog(@"Book 2 subject : %@\n", Book2.subject);
   NSLog(@"Book 2 book_id : %d\n", Book2.book_id);

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 04:20:07.947 demo[20591] Book 1 title : Objective-C Programming
2013-09-14 04:20:07.947 demo[20591] Book 1 author : Nuha Ali
2013-09-14 04:20:07.947 demo[20591] Book 1 subject : Objective-C Programming Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 1 book_id : 6495407
2013-09-14 04:20:07.947 demo[20591] Book 2 title : Telecom Billing
2013-09-14 04:20:07.947 demo[20591] Book 2 author : Zara Ali
2013-09-14 04:20:07.947 demo[20591] Book 2 subject : Telecom Billing Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 2 book_id : 6495700

함수 인수로서의 구조

다른 변수 나 포인터를 전달하는 것과 매우 유사한 방식으로 구조를 함수 인수로 전달할 수 있습니다. 위의 예에서 접근 한 것과 비슷한 방식으로 구조 변수에 접근 할 수 있습니다.

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* function declaration */
- (void) printBook:( struct Books) book ;
@end

@implementation SampleClass 

- (void) printBook:( struct Books) book {
   NSLog(@"Book title : %@\n", book.title);
   NSLog(@"Book author : %@\n", book.author);
   NSLog(@"Book subject : %@\n", book.subject);
   NSLog(@"Book book_id : %d\n", book.book_id);
}

@end

int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info */
   [sampleClass printBook: Book1];

   /* Print Book2 info */
   [sampleClass printBook: Book2];

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 04:34:45.725 demo[8060] Book title : Objective-C Programming
2013-09-14 04:34:45.725 demo[8060] Book author : Nuha Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Objective-C Programming Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495407
2013-09-14 04:34:45.725 demo[8060] Book title : Telecom Billing
2013-09-14 04:34:45.725 demo[8060] Book author : Zara Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Telecom Billing Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495700

구조에 대한 포인터

다음과 같이 다른 변수에 대한 포인터를 정의하는 것과 매우 유사한 방식으로 구조에 대한 포인터를 정의 할 수 있습니다.

struct Books *struct_pointer;

이제 위에서 정의한 포인터 변수에 구조 변수의 주소를 저장할 수 있습니다. 구조 변수의 주소를 찾으려면 다음과 같이 구조 이름 앞에 & 연산자를 배치하십시오.

struct_pointer = &Book1;

해당 구조에 대한 포인터를 사용하여 구조의 멤버에 액세스하려면 다음과 같이-> 연산자를 사용해야합니다.

struct_pointer->title;

구조 포인터를 사용하여 위의 예를 다시 작성해 보겠습니다. 개념을 이해하기 쉽기를 바랍니다.

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* function declaration */
- (void) printBook:( struct Books *) book ;
@end

@implementation SampleClass 
- (void) printBook:( struct Books *) book {
   NSLog(@"Book title : %@\n", book->title);
   NSLog(@"Book author : %@\n", book->author);
   NSLog(@"Book subject : %@\n", book->subject);
   NSLog(@"Book book_id : %d\n", book->book_id);
}

@end

int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info by passing address of Book1 */
   [sampleClass printBook:&Book1];

   /* print Book2 info by passing address of Book2 */
   [sampleClass printBook:&Book2];

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 04:38:13.942 demo[20745] Book title : Objective-C Programming
2013-09-14 04:38:13.942 demo[20745] Book author : Nuha Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Objective-C Programming Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495407
2013-09-14 04:38:13.942 demo[20745] Book title : Telecom Billing
2013-09-14 04:38:13.942 demo[20745] Book author : Zara Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Telecom Billing Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495700

비트 필드

비트 필드를 사용하면 구조에 데이터를 패킹 할 수 있습니다. 이것은 메모리 또는 데이터 저장이 부족할 때 특히 유용합니다. 전형적인 예-

  • 여러 개체를 기계어에 패킹합니다. 예를 들어 1 비트 플래그를 압축 할 수 있습니다.

  • 외부 파일 형식 읽기-비표준 파일 형식을 읽을 수 있습니다. 예 : 9 비트 정수.

Objective-C를 사용하면 변수 뒤에 : bit 길이를 넣어 구조 정의에서이를 수행 할 수 있습니다. 예를 들면-

struct packed_struct {
   unsigned int f1:1;
   unsigned int f2:1;
   unsigned int f3:1;
   unsigned int f4:1;
   unsigned int type:4;
   unsigned int my_int:9;
} pack;

여기서, packed_struct는 6 개의 멤버를 포함합니다 : 4 개의 1 비트 플래그 f1..f3, 4 비트 유형 및 9 비트 my_int.

Objective-C는 필드의 최대 길이가 컴퓨터의 정수 단어 길이보다 작거나 같은 경우 위의 비트 필드를 가능한 한 압축하여 자동으로 압축합니다. 그렇지 않은 경우 일부 컴파일러는 필드에 대해 메모리 겹침을 허용하고 다른 컴파일러는 다음 단어에 다음 필드를 저장합니다.

그만큼 Objective-C Preprocessor컴파일러의 일부는 아니지만 컴파일 프로세스에서 별도의 단계입니다. 간단히 말해서 Objective-C 전처리 기는 텍스트 대체 도구 일 뿐이며 실제 컴파일 전에 필요한 전처리를 수행하도록 컴파일러에 지시합니다. Objective-C 전처리기를 OCPP라고합니다.

모든 전 처리기 명령은 파운드 기호 (#)로 시작합니다. 공백이 아닌 첫 번째 문자 여야하며 가독성을 위해 전 처리기 지시문은 첫 번째 열에서 시작해야합니다. 다음 섹션은 모든 중요한 전 처리기 지시문을 나열합니다.

Sr. 아니. 지침 및 설명
1

#define

전 처리기 매크로를 대체합니다.

2

#include

다른 파일에서 특정 헤더를 삽입합니다.

#undef

전 처리기 매크로 정의 해제

4

#ifdef

이 매크로가 정의 된 경우 true를 반환합니다.

5

#ifndef

이 매크로가 정의되지 않은 경우 true를 반환합니다.

6

#if

컴파일 시간 조건이 참인지 테스트합니다.

7

#else

#if의 대안

8

#elif

#else an #if in one statement

9

#endif

전 처리기 조건부 종료

10

#error

stderr에 오류 메시지를 인쇄합니다.

11

#pragma

표준화 된 방법을 사용하여 컴파일러에 특수 명령을 실행합니다.

전 처리기 예

다음 예제를 분석하여 다양한 지시문을 이해하십시오.

#define MAX_ARRAY_LENGTH 20

이 지시문은 OCPP에 MAX_ARRAY_LENGTH 인스턴스를 20으로 대체하도록 지시합니다 . 가독성을 높이려면 상수에 #define 을 사용하십시오 .

#import <Foundation/Foundation.h>
#include "myheader.h"

이 지시문은 OCPP에 Foundation Framework현재 소스 파일에 텍스트를 추가합니다. 다음 줄은 OCPP에게myheader.h 로컬 디렉토리에서 컨텐츠를 현재 소스 파일에 추가하십시오.

#undef  FILE_SIZE
#define FILE_SIZE 42

이것은 OCPP에 기존 FILE_SIZE를 정의 해제하고 42로 정의하도록 지시합니다.

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

이것은 MESSAGE가 아직 정의되지 않은 경우에만 MESSAGE를 정의하도록 OCPP에 지시합니다.

#ifdef DEBUG
   /* Your debugging statements here */
#endif

이것은 DEBUG가 정의 된 경우 동봉 된 명령문을 처리하도록 OCPP에 지시합니다. 컴파일 할 때 -DDEBUG 플래그를 gcc 컴파일러에 전달하면 유용합니다 . 이것은 DEBUG를 정의하므로 컴파일하는 동안 즉시 디버깅을 켜고 끌 수 있습니다.

미리 정의 된 매크로

ANSI C는 많은 매크로를 정의합니다. 프로그래밍에서 각각 사용할 수 있지만 사전 정의 된 매크로를 직접 수정해서는 안됩니다.

Sr. 아니. 매크로 및 설명
1

__DATE__

"MMM DD YYYY"형식의 문자 리터럴로 표시되는 현재 날짜

2

__TIME__

현재 시간 ( "HH : MM : SS"형식의 문자 리터럴)

__FILE__

현재 파일 이름을 문자열 리터럴로 포함합니다.

4

__LINE__

여기에는 10 진수 상수로 현재 줄 번호가 포함됩니다.

5

__STDC__

컴파일러가 ANSI 표준을 준수하는 경우 1로 정의됩니다.

다음 예를 들어 보겠습니다.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"File :%s\n", __FILE__ );
   NSLog(@"Date :%s\n", __DATE__ );
   NSLog(@"Time :%s\n", __TIME__ );
   NSLog(@"Line :%d\n", __LINE__ );
   NSLog(@"ANSI :%d\n", __STDC__ );
   
   return 0;
}

파일의 위 코드가 main.m 컴파일되고 실행되면 다음 결과가 생성됩니다.

2013-09-14 04:46:14.859 demo[20683] File :main.m
2013-09-14 04:46:14.859 demo[20683] Date :Sep 14 2013
2013-09-14 04:46:14.859 demo[20683] Time :04:46:14
2013-09-14 04:46:14.859 demo[20683] Line :8
2013-09-14 04:46:14.859 demo[20683] ANSI :1

전 처리기 연산자

Objective-C 전처리 기는 매크로 생성에 도움이되는 다음 연산자를 제공합니다.

매크로 연속 (\)

일반적으로 매크로는 한 줄에 포함되어야합니다. 매크로 연속 연산자는 한 줄에 비해 너무 긴 매크로를 계속하는 데 사용됩니다. 예를 들면-

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

스트링 화 (#)

문자열 화 또는 숫자 기호 연산자 ( '#')는 매크로 정의 내에서 사용될 때 매크로 매개 변수를 문자열 상수로 변환합니다. 이 연산자는 지정된 인수 또는 매개 변수 목록이있는 매크로에서만 사용할 수 있습니다. 예를 들면-

#import <Foundation/Foundation.h>

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

int main(void) {
   message_for(Carole, Debra);
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!

토큰 붙여 넣기 (##)

매크로 정의 내의 토큰 붙여 넣기 연산자 (##)는 두 인수를 결합합니다. 매크로 정의에서 두 개의 개별 토큰을 단일 토큰으로 결합 할 수 있습니다. 예를 들면-

#import <Foundation/Foundation.h>

#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)

int main(void) {
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 05:48:14.859 demo[20683] token34 = 40

이 예제는 전 처리기에서 다음과 같은 실제 출력을 생성하기 때문에 어떻게 발생했는지-

NSLog (@"token34 = %d", token34);

이 예제는 token ## n을 token34로 연결하는 것을 보여줍니다. stringizetoken-pasting.

defined () 연산자

전 처리기 defined연산자는 #define을 사용하여 식별자가 정의되었는지 확인하기 위해 상수 표현식에서 사용됩니다. 지정된 식별자가 정의 된 경우 값은 true (0이 아님)입니다. 기호가 정의되지 않은 경우 값은 false (영)입니다. 정의 된 연산자는 다음과 같이 지정됩니다.

#import <Foundation/Foundation.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void) {
   NSLog(@"Here is the message: %s\n", MESSAGE);  
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!

매개 변수화 된 매크로

OCPP의 강력한 기능 중 하나는 매개 변수화 된 매크로를 사용하여 기능을 시뮬레이션하는 기능입니다. 예를 들어, 다음과 같이 숫자를 제곱하는 코드가있을 수 있습니다.

int square(int x) {
   return x * x;
}

다음과 같이 매크로를 사용하여 위의 코드를 다시 작성할 수 있습니다.

#define square(x) ((x) * (x))

인수가있는 매크로는 다음을 사용하여 정의해야합니다. #define지시문을 사용하기 전에. 인수 목록은 괄호로 묶여 있으며 매크로 이름 바로 뒤에 와야합니다. 매크로 이름과 여는 괄호 사이에는 공백이 허용되지 않습니다. 예를 들면-

#import <Foundation/Foundation.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void) {
   NSLog(@"Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20

Objective-C 프로그래밍 언어는 typedef, 유형에 새 이름을 지정하는 데 사용할 수 있습니다. 다음은 용어를 정의하는 예입니다.BYTE 1 바이트 숫자-

typedef unsigned char BYTE;

이 유형 정의 후에 식별자 BYTE를 유형의 약어로 사용할 수 있습니다. unsigned char, for example:.

BYTE  b1, b2;

관례 상 대문자는 이러한 정의에 사용되어 유형 이름이 실제로 기호 약어임을 사용자에게 상기시켜 주지만 다음과 같이 소문자를 사용할 수 있습니다.

typedef unsigned char byte;

당신이 사용할 수있는 typedef사용자 정의 데이터 유형에도 이름을 부여합니다. 예를 들어, 구조와 함께 typedef를 사용하여 새 데이터 유형을 정의한 다음 해당 데이터 유형을 사용하여 다음과 같이 구조 변수를 직접 정의 할 수 있습니다.

#import <Foundation/Foundation.h>

typedef struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int book_id;
} Book;
 
int main() {
   Book book;
   book.title = @"Objective-C Programming";
   book.author = @"TutorialsPoint";
   book.subject = @"Programming tutorial";
   book.book_id = 100;
   
   NSLog( @"Book title : %@\n", book.title);
   NSLog( @"Book author : %@\n", book.author);
   NSLog( @"Book subject : %@\n", book.subject);
   NSLog( @"Book Id : %d\n", book.book_id);

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-12 12:21:53.745 demo[31183] Book title : Objective-C Programming
2013-09-12 12:21:53.745 demo[31183] Book author : TutorialsPoint
2013-09-12 12:21:53.745 demo[31183] Book subject : Programming tutorial
2013-09-12 12:21:53.745 demo[31183] Book Id : 100

typedef 대 #define

그만큼 #define Objective-C 지시문으로, 다음과 유사한 다양한 데이터 유형에 대한 별칭을 정의하는데도 사용됩니다. typedef 그러나 다음과 같은 차이점이 있습니다.

  • 그만큼 typedef 유형에만 기호 이름을 제공하는 것으로 제한되지만 #define 1을 ONE으로 정의 할 수있는 것처럼 값의 별칭을 정의하는데도 사용할 수 있습니다.

  • 그만큼 typedef 해석은 컴파일러에 의해 수행됩니다. #define 명령문은 전처리기에 의해 처리됩니다.

다음은 #define의 가장 간단한 사용법입니다.

#import <Foundation/Foundation.h>
 
#define TRUE  1
#define FALSE 0
 
int main( ) {
   NSLog( @"Value of TRUE : %d\n", TRUE);
   NSLog( @"Value of FALSE : %d\n", FALSE);

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-12 12:23:37.993 demo[5160] Value of TRUE : 1
2013-09-12 12:23:37.994 demo[5160] Value of FALSE : 0

유형 캐스팅은 한 데이터 유형에서 다른 데이터 유형으로 변수를 변환하는 방법입니다. 예를 들어, long 값을 간단한 정수에 저장하려면 cast long을 int로 입력 할 수 있습니다. 다음을 사용하여 한 유형에서 다른 유형으로 값을 명시 적으로 변환 할 수 있습니다.cast operator 다음과 같이-

(type_name) expression

Objective-C에서는 일반적으로 부동 소수점 연산을 수행하기 위해 CGFloat를 사용하는데, 이는 32 비트의 경우 기본 유형의 float, 64 비트의 경우 double에서 파생됩니다. 캐스트 연산자가 한 정수 변수를 다른 정수 변수로 나누면 부동 소수점 연산으로 수행되는 다음 예제를 고려하십시오.

#import <Foundation/Foundation.h>

int main() {
   int sum = 17, count = 5;
   CGFloat mean;

   mean = (CGFloat) sum / count;
   NSLog(@"Value of mean : %f\n", mean );

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-11 01:35:40.047 demo[20634] Value of mean : 3.400000

여기서 캐스트 연산자는 나누기보다 우선하므로 sum 먼저 유형으로 변환됩니다. double 마지막으로 두 배의 값을 산출하는 개수로 나뉩니다.

유형 변환은 컴파일러에 의해 자동으로 수행되는 암시 적이거나 다음을 사용하여 명시 적으로 지정 될 수 있습니다. cast operator. 유형 변환이 필요할 때마다 캐스트 연산자를 사용하는 것이 좋은 프로그래밍 관행으로 간주됩니다.

정수 승격

정수 승격은 정수 유형의 값이 다음보다 "작은"프로세스입니다. int 또는 unsigned int 다음 중 하나로 변환됩니다. int 또는 unsigned int. int에 문자를 추가하는 예를 고려하십시오.

#import <Foundation/Foundation.h>

int main() {
   int  i = 17;
   char c = 'c';  /* ascii value is 99 */
   int sum;

   sum = i + c;
   NSLog(@"Value of sum : %d\n", sum );

   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-11 01:38:28.492 demo[980] Value of sum : 116

여기서 컴파일러는 정수 승격을하고 실제 더하기 연산을 수행하기 전에 'c'의 값을 ascii로 변환하기 때문에 sum의 값은 116이됩니다.

일반적인 산술 변환

그만큼 usual arithmetic conversions공통 유형으로 값을 캐스트하기 위해 암시 적으로 수행됩니다. 컴파일러는 먼저 정수 승격을 수행 합니다. 피연산자가 여전히 다른 유형을 가지고있는 경우 다음 계층에서 가장 높은 유형으로 변환됩니다.

일반적인 산술 변환은 할당 연산자 나 논리 연산자 && 및 ||에 대해 수행되지 않습니다. 개념을 이해하기 위해 다음 예를 들어 보겠습니다.

#import <Foundation/Foundation.h>

int main() {
   int  i = 17;
   char c = 'c';  /* ascii value is 99 */
   CGFloat sum;

   sum = i + c;
   NSLog(@"Value of sum : %f\n", sum );
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-11 01:41:39.192 demo[15351] Value of sum : 116.000000

여기서 첫 번째 c는 정수로 변환되지만 최종 값은 float이기 때문에 일반적인 산술 변환이 적용되고 컴파일러는 i와 c를 float로 변환하고이를 추가하여 float 결과를 산출한다는 것을 이해하는 것은 간단합니다.

NSLog 방법

로그를 인쇄하기 위해 Hello World 예제에서 바로 사용했던 Objective-C 프로그래밍 언어의 NSLog 메서드를 사용합니다.

"Hello World"라는 단어를 인쇄하는 간단한 코드를 살펴 보겠습니다.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Hello, World! \n");
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-16 00:32:50.888 demo[16669] Hello, World!

라이브 앱에서 로그 비활성화

응용 프로그램에서 사용하는 NSLog는 장치의 로그에 인쇄되므로 라이브 빌드에서 로그를 인쇄하는 것은 좋지 않습니다. 따라서 로그 인쇄를 위해 유형 정의를 사용하며 아래와 같이 사용할 수 있습니다.

#import <Foundation/Foundation.h>

#if DEBUG == 0
#define DebugLog(...)
#elif DEBUG == 1
#define DebugLog(...) NSLog(__VA_ARGS__)
#endif

int main() {
   DebugLog(@"Debug log, our custom addition gets \
   printed during debug only" );
   NSLog(@"NSLog gets printed always" );     
   return 0;
}

이제 디버그 모드에서 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-11 02:47:07.723 demo[618] Debug log, our custom addition gets printed during debug only
2013-09-11 02:47:07.723 demo[618] NSLog gets printed always

이제 릴리스 모드에서 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-11 02:47:45.248 demo[3158] NSLog gets printed always

Objective-C 프로그래밍에서 오류 처리는 다음에서 사용할 수있는 NSError 클래스로 제공됩니다. Foundation framework.

NSError 객체는 오류 코드 또는 오류 문자열만을 사용하여 가능한 것보다 더 풍부하고 확장 가능한 오류 정보를 캡슐화합니다. NSError 객체의 핵심 속성은 오류 도메인 (문자열로 표시), 도메인 별 오류 코드 및 애플리케이션 별 정보를 포함하는 사용자 정보 사전입니다.

NSError

Objective-C 프로그램은 NSError 객체를 사용하여 사용자에게 알려야하는 런타임 오류에 대한 정보를 전달합니다. 대부분의 경우 프로그램은이 오류 정보를 대화 상자 나 시트에 표시합니다. 그러나 정보를 해석하고 사용자에게 오류 복구를 시도하거나 스스로 오류를 수정하도록 요청할 수도 있습니다.

NSError 객체는-

  • Domain − 오류 도메인은 미리 정의 된 NSError 도메인 중 하나이거나 사용자 지정 도메인을 설명하는 임의의 문자열 일 수 있으며 도메인은 nil이 아니어야합니다.

  • Code − 오류에 대한 오류 코드.

  • User Info − 오류에 대한 userInfo 사전 및 userInfo는 nil 일 수 있습니다.

다음 예제는 사용자 지정 오류를 만드는 방법을 보여줍니다.

NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
NSString *desc = NSLocalizedString(@"Unable to complete the process", @"");
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo];

다음은 포인터에 대한 참조로 전달 된 위의 오류 샘플의 완전한 코드입니다.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr;
@end

@implementation SampleClass

-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr {
   if(id == 1) {
      return @"Employee Test Name";
   } else {
      NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
      NSString *desc =@"Unable to complete the process";
      NSDictionary *userInfo = [[NSDictionary alloc] 
      initWithObjectsAndKeys:desc,
      @"NSLocalizedDescriptionKey",NULL];  
      *errorPtr = [NSError errorWithDomain:domain code:-101 
      userInfo:userInfo];
      return @"";
   }
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   NSError *error = nil;
   NSString *name1 = [sampleClass getEmployeeNameForID:1 withError:&error];
  
   if(error) {
      NSLog(@"Error finding Name1: %@",error);
   } else {
      NSLog(@"Name1: %@",name1);
   }
   
   error = nil;
   NSString *name2 = [sampleClass getEmployeeNameForID:2 withError:&error];

   if(error) {
      NSLog(@"Error finding Name2: %@",error);
   } else {
      NSLog(@"Name2: %@",name2);
   }

   [pool drain];
   return 0; 
}

위의 예에서 id가 1이면 이름을 반환하고 그렇지 않으면 사용자 정의 오류 개체를 설정합니다.

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-14 18:01:00.809 demo[27632] Name1: Employee Test Name
2013-09-14 18:01:00.809 demo[27632] Error finding Name2: Unable to complete the process

명령 줄에서 Objective-C 프로그램이 실행될 때 일부 값을 전달할 수 있습니다. 이러한 값은command line arguments 특히 코드 내부에서 해당 값을 하드 코딩하는 대신 외부에서 프로그램을 제어하려는 경우 특히 프로그램에 중요합니다.

명령 줄 인수는 main () 함수 인수를 사용하여 처리됩니다. argc 전달 된 인수의 수를 나타냅니다. argv[]프로그램에 전달 된 각 인수를 가리키는 포인터 배열입니다. 다음은 명령 줄에서 제공된 인수가 있는지 확인하고 그에 따라 조치를 취하는 간단한 예입니다.

#import <Foundation/Foundation.h>

int main( int argc, char *argv[] ) {
   if( argc == 2 ) {
      NSLog(@"The argument supplied is %s\n", argv[1]);
   } else if( argc > 2 ) {
      NSLog(@"Too many arguments supplied.\n");
   } else {
      NSLog(@"One argument expected.\n");
   }
}

위의 코드가 "testing"이라는 단일 인수로 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-13 03:01:17.333 demo[7640] The argument supplied is testing

위의 코드가 testing1과 testing2의 두 인수로 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-13 03:01:18.333 demo[7640] Too many arguments supplied.

위의 코드를 인자를 전달하지 않고 컴파일하여 실행하면 다음과 같은 결과가 나옵니다.

2013-09-13 03:01:18.333 demo[7640] One argument expected

유의해야합니다 argv[0] 프로그램 자체의 이름을 보유하고 argv[1]제공된 첫 번째 명령 줄 인수에 대한 포인터이고 * argv [n]은 마지막 인수입니다. 인수가 제공되지 않으면 argc가 1이되고, 그렇지 않으면 인수를 전달하면argc 2로 설정됩니다.

공백으로 구분 된 모든 명령 줄 인수를 전달하지만 인수 자체에 공백이있는 경우 이러한 인수를 큰 따옴표 ""또는 작은 따옴표 ''안에 넣어 전달할 수 있습니다. 위의 예를 다시 작성하여 프로그램 이름을 인쇄하고 큰 따옴표 안에 명령 줄 인수를 전달합니다.

#import <Foundation/Foundation.h>

int main( int argc, char *argv[] ) {
   NSLog(@"Program name %s\n", argv[0]);
 
   if( argc == 2 ) {
      NSLog(@"The argument supplied is %s\n", argv[1]);
   } else if( argc > 2 ) {
      NSLog(@"Too many arguments supplied.\n");
   } else {
      NSLog(@"One argument expected.\n");
   }
   
   return 0;
}

위의 코드가 공백으로 구분 된 단일 인수로 컴파일 및 실행되지만 큰 따옴표 안에 "Testing1 Testing2"라고 표시되면 다음과 같은 결과가 생성됩니다.

2017-11-30 06:36:59.081 main[71010] Program name main
2017-11-30 06:36:59.082 main[71010] One argument expected.

Objective-C 프로그래밍 언어의 주요 목적은 C 프로그래밍 언어에 객체 지향을 추가하는 것이며 클래스는 객체 지향 프로그래밍을 지원하는 Objective-C의 핵심 기능이며 종종 사용자 정의 유형이라고합니다.

클래스는 객체의 형태를 지정하는 데 사용되며 데이터 표현과 해당 데이터를 하나의 깔끔한 패키지로 조작하기위한 메서드를 결합합니다. 클래스 내의 데이터와 메서드를 클래스의 멤버라고합니다.

Objective-C 특성

  • 클래스는 두 개의 다른 섹션에서 정의됩니다. @interface@implementation.

  • 거의 모든 것이 물체의 형태입니다.

  • 객체는 메시지를 수신하고 객체는 종종 수신자라고합니다.

  • 개체에는 인스턴스 변수가 포함됩니다.

  • 개체 및 인스턴스 변수에는 범위가 있습니다.

  • 클래스는 객체의 구현을 숨 깁니다.

  • 속성은 다른 클래스의 클래스 인스턴스 변수에 대한 액세스를 제공하는 데 사용됩니다.

Objective-C 클래스 정의

클래스를 정의 할 때 데이터 유형에 대한 청사진을 정의합니다. 이것은 실제로 어떤 데이터도 정의하지 않지만 클래스 이름이 의미하는 바, 즉 클래스의 객체가 구성되는 것과 그러한 객체에서 수행 할 수있는 작업을 정의합니다.

클래스 정의는 키워드로 시작합니다. @interface인터페이스 (클래스) 이름이 뒤 따릅니다. 클래스 본문은 중괄호 쌍으로 묶여 있습니다. Objective-C에서 모든 클래스는 다음과 같은 기본 클래스에서 파생됩니다.NSObject. 모든 Objective-C 클래스의 수퍼 클래스입니다. 메모리 할당 및 초기화와 같은 기본 방법을 제공합니다. 예를 들어, 우리는 키워드를 사용하여 Box 데이터 유형을 정의했습니다.class 다음과 같이-

@interface Box:NSObject {
   //Instance variables
   double length;    // Length of a box
   double breadth;   // Breadth of a box
}
@property(nonatomic, readwrite) double height;  // Property

@end

인스턴스 변수는 비공개이며 클래스 구현 내에서만 액세스 할 수 있습니다.

Objective-C 객체 할당 및 초기화

클래스는 객체에 대한 청사진을 제공하므로 기본적으로 객체는 클래스에서 생성됩니다. 기본 유형의 변수를 선언하는 것과 똑같은 종류의 선언으로 클래스의 객체를 선언합니다. 다음 명령문은 Box 클래스의 두 객체를 선언합니다-

Box box1 = [[Box alloc]init];     // Create box1 object of type Box
Box box2 = [[Box alloc]init];     // Create box2 object of type Box

box1 및 box2 개체는 모두 데이터 멤버의 자체 복사본을 갖습니다.

데이터 멤버에 액세스

클래스 개체의 속성은 직접 멤버 액세스 연산자 (.)를 사용하여 액세스 할 수 있습니다. 명확하게하기 위해 다음 예제를 시도해 보겠습니다.

#import <Foundation/Foundation.h>

@interface Box:NSObject {
   double length;    // Length of a box
   double breadth;   // Breadth of a box
   double height;    // Height of a box
}

@property(nonatomic, readwrite) double height;  // Property
-(double) volume;
@end

@implementation Box

@synthesize height; 

-(id)init {
   self = [super init];
   length = 1.0;
   breadth = 1.0;
   return self;
}

-(double) volume {
   return length*breadth*height;
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
   Box *box1 = [[Box alloc]init];    // Create box1 object of type Box
   Box *box2 = [[Box alloc]init];    // Create box2 object of type Box

   double volume = 0.0;             // Store the volume of a box here
 
   // box 1 specification
   box1.height = 5.0; 

   // box 2 specification
   box2.height = 10.0;
  
   // volume of box 1
   volume = [box1 volume];
   NSLog(@"Volume of Box1 : %f", volume);
   
   // volume of box 2
   volume = [box2 volume];
   NSLog(@"Volume of Box2 : %f", volume);
   
   [pool drain];
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-22 21:25:33.314 ClassAndObjects[387:303] Volume of Box1 : 5.000000
2013-09-22 21:25:33.316 ClassAndObjects[387:303] Volume of Box2 : 10.000000

속성

Objective-C에는 클래스 외부에서 클래스의 인스턴스 변수에 액세스 할 수 있도록 속성이 도입되었습니다.

  • 속성 시작 @property, 키워드

  • 그 뒤에는 비원 자적 또는 원자 적, 읽기 쓰기 또는 읽기 전용이고 strong, unsafe_unretained 또는 weak 인 액세스 지정자가 있습니다. 이것은 변수의 유형에 따라 다릅니다. 모든 포인터 유형에 대해 strong, unsafe_unretained 또는 weak를 사용할 수 있습니다. 다른 유형에서도 마찬가지로 readwrite 또는 readonly를 사용할 수 있습니다.

  • 그 다음에는 변수의 데이터 유형이옵니다.

  • 마지막으로 세미콜론으로 끝나는 속성 이름이 있습니다.

  • 구현 클래스에 synthesize 문을 추가 할 수 있습니다. 그러나 최신 XCode에서는 합성 부분이 XCode에 의해 처리되므로 synthesize 문을 포함 할 필요가 없습니다.

클래스의 인스턴스 변수에 액세스 할 수있는 속성으로 만 가능합니다. 실제로 내부적으로 속성에 대해 getter 및 setter 메서드가 생성됩니다.

예를 들어 속성이 있다고 가정 해 보겠습니다. @property (nonatomic ,readonly ) BOOL isDone. 후드 아래에는 아래와 같이 생성 된 세터와 게터가 있습니다.

-(void)setIsDone(BOOL)isDone;
-(BOOL)isDone;

객체 지향 프로그래밍에서 가장 중요한 개념 중 하나는 상속입니다. 상속을 통해 다른 클래스의 관점에서 클래스를 정의 할 수 있으므로 응용 프로그램을 쉽게 만들고 유지 관리 할 수 ​​있습니다. 또한 코드 기능을 재사용 할 수있는 기회와 빠른 구현 시간을 제공합니다.

클래스를 만들 때 완전히 새로운 데이터 멤버와 멤버 함수를 작성하는 대신 프로그래머는 새 클래스가 기존 클래스의 멤버를 상속하도록 지정할 수 있습니다. 이 기존 클래스를base 클래스, 새 클래스는 derived 수업.

상속의 개념은 is a관계. 예를 들어, 포유류 IS-A 동물, 개 IS-A 포유류, 따라서 개 IS-A 동물도 마찬가지입니다.

기본 및 파생 클래스

Objective-C는 다중 수준 상속 만 허용합니다. 즉, 하나의 기본 클래스 만 가질 수 있지만 다중 수준 상속은 허용합니다. Objective-C의 모든 클래스는 수퍼 클래스에서 파생됩니다.NSObject.

@interface derived-class: base-class

기본 클래스 고려 Person 및 파생 클래스 Employee 다음과 같이-

#import <Foundation/Foundation.h>
 
@interface Person : NSObject {
   NSString *personName;
   NSInteger personAge;
}

- (id)initWithName:(NSString *)name andAge:(NSInteger)age;
- (void)print;

@end

@implementation Person

- (id)initWithName:(NSString *)name andAge:(NSInteger)age {
   personName = name;
   personAge = age;
   return self;
}

- (void)print {
   NSLog(@"Name: %@", personName);
   NSLog(@"Age: %ld", personAge);
}

@end

@interface Employee : Person {
   NSString *employeeEducation;
}

- (id)initWithName:(NSString *)name andAge:(NSInteger)age 
  andEducation:(NSString *)education;
- (void)print;
@end

@implementation Employee

- (id)initWithName:(NSString *)name andAge:(NSInteger)age 
   andEducation: (NSString *)education {
      personName = name;
      personAge = age;
      employeeEducation = education;
      return self;
   }

- (void)print {
   NSLog(@"Name: %@", personName);
   NSLog(@"Age: %ld", personAge);
   NSLog(@"Education: %@", employeeEducation);
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];        
   NSLog(@"Base class Person Object");
   Person *person = [[Person alloc]initWithName:@"Raj" andAge:5];
   [person print];
   NSLog(@"Inherited Class Employee Object");
   Employee *employee = [[Employee alloc]initWithName:@"Raj" 
   andAge:5 andEducation:@"MBA"];
   [employee print];        
   [pool drain];
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-22 21:20:09.842 Inheritance[349:303] Base class Person Object
2013-09-22 21:20:09.844 Inheritance[349:303] Name: Raj
2013-09-22 21:20:09.844 Inheritance[349:303] Age: 5
2013-09-22 21:20:09.845 Inheritance[349:303] Inherited Class Employee Object
2013-09-22 21:20:09.845 Inheritance[349:303] Name: Raj
2013-09-22 21:20:09.846 Inheritance[349:303] Age: 5
2013-09-22 21:20:09.846 Inheritance[349:303] Education: MBA

액세스 제어 및 상속

파생 클래스는 인터페이스 클래스에 정의 된 경우 기본 클래스의 모든 전용 멤버에 액세스 할 수 있지만 구현 파일에 정의 된 전용 멤버에는 액세스 할 수 없습니다.

다음과 같은 방법으로 액세스 할 수있는 사람에 따라 다양한 액세스 유형을 요약 할 수 있습니다.

파생 클래스는 다음 예외를 제외하고 모든 기본 클래스 메서드와 변수를 상속합니다.

  • 확장의 도움으로 구현 파일에 선언 된 변수에 액세스 할 수 없습니다.

  • 확장의 도움으로 구현 파일에 선언 된 메서드에 액세스 할 수 없습니다.

  • 상속 된 클래스가 기본 클래스의 메서드를 구현하는 경우 파생 클래스의 메서드가 실행됩니다.

단어 polymorphism다양한 형태를 갖는 것을 의미합니다. 일반적으로 다형성은 클래스 계층 구조가 있고 상속에 의해 관련 될 때 발생합니다.

Objective-C 다형성은 멤버 함수를 호출하면 함수를 호출하는 객체의 유형에 따라 다른 함수가 실행됨을 의미합니다.

예를 들어, 모든 모양에 대한 기본 인터페이스를 제공하는 Shape 클래스가 있습니다. Square 및 Rectangle은 기본 클래스 Shape에서 파생됩니다.

OOP 기능에 대해 보여줄 printArea 메소드가 있습니다. polymorphism.

#import <Foundation/Foundation.h>

@interface Shape : NSObject {
   CGFloat area;
}

- (void)printArea;
- (void)calculateArea;
@end

@implementation Shape
- (void)printArea {
   NSLog(@"The area is %f", area);
}

- (void)calculateArea {

}

@end

@interface Square : Shape {
   CGFloat length;
}

- (id)initWithSide:(CGFloat)side;
- (void)calculateArea;

@end

@implementation Square
- (id)initWithSide:(CGFloat)side {
   length = side;
   return self;
}

- (void)calculateArea {
   area = length * length;
}

- (void)printArea {
   NSLog(@"The area of square is %f", area);
}

@end

@interface Rectangle : Shape {
   CGFloat length;
   CGFloat breadth;
}

- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth;
@end

@implementation Rectangle
- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth {
   length = rLength;
   breadth = rBreadth;
   return self;
}

- (void)calculateArea {
   area = length * breadth;
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   Shape *square = [[Square alloc]initWithSide:10.0];
   [square calculateArea];
   [square printArea];
   Shape *rect = [[Rectangle alloc]
   initWithLength:10.0 andBreadth:5.0];
   [rect calculateArea];
   [rect printArea];        
   [pool drain];
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-22 21:21:50.785 Polymorphism[358:303] The area of square is 100.000000
2013-09-22 21:21:50.786 Polymorphism[358:303] The area is 50.000000

위의 예제에서 computeArea 및 printArea 메서드의 가용성에 따라 기본 클래스의 메서드 또는 파생 클래스가 실행되었습니다.

다형성은 두 클래스의 메서드 구현을 기반으로 기본 클래스와 파생 클래스 간의 메서드 전환을 처리합니다.

모든 Objective-C 프로그램은 다음 두 가지 기본 요소로 구성됩니다.

  • Program statements (code) − 이것은 작업을 수행하는 프로그램의 일부이며 메서드라고합니다.

  • Program data − 데이터는 프로그램 기능의 영향을받는 프로그램의 정보입니다.

캡슐화는 데이터를 조작하는 데이터와 함수를 결합하고 외부 간섭과 오용으로부터 안전하게 보호하는 객체 지향 프로그래밍 개념입니다. 데이터 캡슐화는 중요한 OOP 개념으로 이어졌습니다.data hiding.

Data encapsulation 데이터와이를 사용하는 기능을 번들링하는 메커니즘입니다. data abstraction 인터페이스 만 노출하고 사용자에게 구현 세부 정보를 숨기는 메커니즘입니다.

Objective-C는 다음과 같은 사용자 정의 유형 생성을 통해 캡슐화 및 데이터 숨김 속성을 지원합니다. classes. 예를 들면-

@interface Adder : NSObject {
   NSInteger total;
}

- (id)initWithInitialNumber:(NSInteger)initialNumber;
- (void)addNumber:(NSInteger)newNumber;
- (NSInteger)getTotal;

@end

변수 total은 비공개이며 클래스 외부에서 액세스 할 수 없습니다. 즉, 프로그램의 다른 부분이 아닌 Adder 클래스의 다른 멤버 만 액세스 할 수 있습니다. 이것은 캡슐화가 이루어지는 한 가지 방법입니다.

인터페이스 파일 내의 메서드에 액세스 할 수 있으며 범위 내에서 공용입니다.

의 도움으로 작성된 개인 방법이 있습니다. extensions, 우리는 다음 장에서 배울 것입니다.

데이터 캡슐화 예

공용 및 개인 멤버 변수로 클래스를 구현하는 Objective-C 프로그램은 데이터 캡슐화 및 데이터 추상화의 예입니다. 다음 예를 고려하십시오-

#import <Foundation/Foundation.h>

@interface Adder : NSObject {
   NSInteger total;
}

- (id)initWithInitialNumber:(NSInteger)initialNumber;
- (void)addNumber:(NSInteger)newNumber;
- (NSInteger)getTotal;

@end

@implementation Adder
-(id)initWithInitialNumber:(NSInteger)initialNumber {
   total = initialNumber;
   return self;
}

- (void)addNumber:(NSInteger)newNumber {
   total = total + newNumber;
}

- (NSInteger)getTotal {
   return total;
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];        
   Adder *adder = [[Adder alloc]initWithInitialNumber:10];
   [adder addNumber:5];
   [adder addNumber:4];
   
   NSLog(@"The total is %ld",[adder getTotal]);
   [pool drain];
   return 0;
}

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

2013-09-22 21:17:30.485 DataEncapsulation[317:303] The total is 19

위의 클래스는 숫자를 더하고 합계를 반환합니다. 공개 회원addNumgetTotal 외부 세계에 대한 인터페이스이며 사용자는 클래스를 사용하기 위해이를 알아야합니다. 개인 회원total 외부 세계에는 숨겨져 있지만 수업이 제대로 작동하려면 필요합니다.

전략 설계

우리 대부분은 실제로 공개 할 필요가없는 한 클래스 멤버를 기본적으로 비공개로 만드는 것을 쓴 경험을 통해 배웠습니다. 그냥 좋다encapsulation.

Objective-C를 포함한 모든 OOP (Object-Oriented Programming) 언어의 핵심 기능 중 하나이기 때문에 데이터 캡슐화를 이해하는 것이 중요합니다.

때로는 특정 상황에서만 유용한 동작을 추가하여 기존 클래스를 확장하려는 경우가 있습니다. 이러한 확장을 기존 클래스에 추가하기 위해 Objective-C는categoriesextensions.

기존 클래스에 메서드를 추가해야하는 경우 (예 : 자신의 응용 프로그램에서 작업을 더 쉽게 수행 할 수있는 기능을 추가해야하는 경우) 가장 쉬운 방법은 범주를 사용하는 것입니다.

범주를 선언하는 구문은 표준 Objective-C 클래스 설명과 마찬가지로 @interface 키워드를 사용하지만 하위 클래스로부터의 상속을 나타내지는 않습니다. 대신 다음과 같이 괄호 안에 카테고리 이름을 지정합니다.

@interface ClassName (CategoryName)

@end

카테고리의 특성

  • 원래 구현 소스 코드가 없더라도 모든 클래스에 대해 범주를 선언 할 수 있습니다.

  • 범주에서 선언하는 모든 메서드는 원본 클래스의 모든 하위 클래스뿐만 아니라 원본 클래스의 모든 인스턴스에서 사용할 수 있습니다.

  • 런타임시 범주에 의해 추가 된 메서드와 원래 클래스에 의해 구현 된 메서드간에 차이가 없습니다.

이제 샘플 카테고리 구현을 살펴 보겠습니다. Cocoa 클래스 NSString에 카테고리를 추가합시다. 이 카테고리를 사용하면 저작권 문자열을 반환하는 데 도움이되는 새 메소드 getCopyRightString을 추가 할 수 있습니다. 아래와 같습니다.

#import <Foundation/Foundation.h>

@interface NSString(MyAdditions)
+(NSString *)getCopyRightString;
@end

@implementation NSString(MyAdditions)

+(NSString *)getCopyRightString {
   return @"Copyright TutorialsPoint.com 2013";
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSString *copyrightString = [NSString getCopyRightString];
   NSLog(@"Accessing Category: %@",copyrightString);
   
   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-22 21:19:12.125 Categories[340:303] Accessing Category: Copyright TutorialsPoint.com 2013

범주에 의해 추가 된 모든 메서드는 클래스 및 하위 클래스의 모든 인스턴스에서 사용할 수 있지만 추가 메서드를 사용하려는 모든 소스 코드 파일에서 범주 헤더 파일을 가져와야합니다. 그렇지 않으면 컴파일러 경고 및 오류.

이 예에서는 클래스가 하나뿐이므로 헤더 파일을 포함하지 않았습니다.이 경우 위에서 말한대로 헤더 파일을 포함해야합니다.

Objective-C에서 Posing에 대해 시작하기 전에 Posing이 Mac OS X 10.5에서 더 이상 사용되지 않는 것으로 선언되었으며 이후에는 사용할 수 없음을 알려드립니다. 따라서 이러한 사용되지 않는 메서드에 대해 걱정하지 않는 사람들은이 장을 건너 뛸 수 있습니다.

Objective-C는 한 클래스가 프로그램 내에서 다른 클래스를 완전히 대체 할 수 있도록합니다. 대체 클래스는 대상 클래스로 "포즈"한다고합니다.

포즈를 지원하는 버전의 경우 대상 클래스로 전송 된 모든 메시지가 포즈 클래스에서 대신 수신됩니다.

NSObject에는 위에서 언급 한 기존 클래스를 대체 할 수있는 poseAsClass : 메소드가 포함되어 있습니다.

포즈 제한

  • 클래스는 직접 또는 간접 수퍼 클래스 중 하나로 만 위장 할 수 있습니다.

  • 포즈 클래스는 대상 클래스에없는 새 인스턴스 변수를 정의하지 않아야합니다 (메소드를 정의하거나 재정의 할 수 있음).

  • 대상 클래스는 포즈를 취하기 전에 메시지를받지 못했을 수 있습니다.

  • 포즈 클래스는 super를 통해 재정의 된 메서드를 호출 할 수 있으므로 대상 클래스의 구현을 통합 할 수 있습니다.

  • 포즈 클래스는 범주에 정의 된 메서드를 재정의 할 수 있습니다.

#import <Foundation/Foundation.h>

@interface MyString : NSString

@end

@implementation MyString

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target
withString:(NSString *)replacement {
   NSLog(@"The Target string is %@",target);
   NSLog(@"The Replacement string is %@",replacement);
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   [MyString poseAsClass:[NSString class]];
   NSString *string = @"Test";
   [string stringByReplacingOccurrencesOfString:@"a" withString:@"c"];
   
   [pool drain];
   return 0;
}

이제 이전 Mac OS X (V_10.5 이하)에서 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-22 21:23:46.829 Posing[372:303] The Target string is a
2013-09-22 21:23:46.830 Posing[372:303] The Replacement string is c

위의 예제에서 우리는 우리의 구현으로 원래의 메서드를 오염 시켰고 이것은 위의 메서드를 사용하는 모든 NSString 작업에 걸쳐 영향을받습니다.

클래스 확장은 범주와 약간 유사하지만 컴파일 타임에 소스 코드가있는 클래스에만 추가 할 수 있습니다 (클래스는 클래스 확장과 동시에 컴파일 됨).

클래스 확장에 의해 선언 된 메서드는 원래 클래스의 구현 블록에서 구현되므로 예를 들어 NSString과 같은 Cocoa 또는 Cocoa Touch 클래스와 같은 프레임 워크 클래스에서 클래스 확장을 선언 할 수 없습니다.

확장자는 실제로 카테고리 이름이없는 카테고리입니다. 종종anonymous categories.

확장을 선언하는 구문은 표준 Objective-C 클래스 설명과 마찬가지로 @interface 키워드를 사용하지만 하위 클래스의 상속을 나타내지는 않습니다. 대신, 아래와 같이 괄호 만 추가합니다.

@interface ClassName ()

@end

확장의 특성

  • 확장은 어떤 클래스에도 선언 할 수 없으며, 소스 코드의 원래 구현이있는 클래스에 대해서만 선언됩니다.

  • 확장은 클래스에만 특정한 개인 메서드와 개인 변수를 추가합니다.

  • 확장 내부에 선언 된 메서드 나 변수는 상속 된 클래스에서도 액세스 할 수 없습니다.

확장 예

확장이있는 SampleClass 클래스를 만들어 보겠습니다. 확장에는 private 변수 internalID가 있습니다.

그런 다음 internalID를 처리 한 후 externalID를 반환하는 getExternalID 메서드를 만들어 보겠습니다.

예제는 아래에 나와 있으며 온라인 컴파일러에서는 작동하지 않습니다.

#import <Foundation/Foundation.h>

@interface SampleClass : NSObject {
   NSString *name;
}

- (void)setInternalID;
- (NSString *)getExternalID;

@end

@interface SampleClass() {
   NSString *internalID;
}

@end

@implementation SampleClass

- (void)setInternalID {
   internalID = [NSString stringWithFormat: 
   @"UNIQUEINTERNALKEY%dUNIQUEINTERNALKEY",arc4random()%100];
}

- (NSString *)getExternalID {
   return [internalID stringByReplacingOccurrencesOfString: 
   @"UNIQUEINTERNALKEY" withString:@""];
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass setInternalID];
   NSLog(@"ExternalID: %@",[sampleClass getExternalID]);        
   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-22 21:18:31.754 Extensions[331:303] ExternalID: 51

위의 예에서 internalID가 직접 반환되지 않음을 알 수 있습니다. 여기서 UNIQUEINTERNALKEY를 제거하고 getExternalID 메소드에서 나머지 값만 사용할 수 있도록합니다.

위의 예는 문자열 연산 만 사용하지만 암호화 / 복호화 등과 같은 많은 기능을 가질 수 있습니다.

Objective-C를 사용하면 특정 상황에 사용될 것으로 예상되는 메서드를 선언하는 프로토콜을 정의 할 수 있습니다. 프로토콜은 프로토콜을 준수하는 클래스에서 구현됩니다.

간단한 예는 네트워크 URL 처리 클래스이며, 네트워크 URL 가져 오기 작업이 끝나면 호출 클래스를 암시하는 processCompleted 대리자 메서드와 같은 메서드가 포함 된 프로토콜이 있습니다.

프로토콜 구문은 다음과 같습니다.

@protocol ProtocolName
@required
// list of required methods
@optional
// list of optional methods
@end

키워드의 방법 @required 프로토콜과 아래의 메소드를 준수하는 클래스에서 구현되어야합니다. @optional 구현할 키워드는 선택 사항입니다.

프로토콜을 준수하는 클래스의 구문은 다음과 같습니다.

@interface MyClass : NSObject <MyProtocol>
...
@end

이것은 MyClass의 모든 인스턴스가 인터페이스에서 특별히 선언 된 메서드에 응답 할뿐만 아니라 MyClass가 MyProtocol에서 필요한 메서드에 대한 구현도 제공한다는 것을 의미합니다. 클래스 인터페이스에서 프로토콜 메서드를 다시 선언 할 필요가 없습니다. 프로토콜을 채택하면 충분합니다.

여러 프로토콜을 채택하기 위해 클래스가 필요한 경우 쉼표로 구분 된 목록으로 지정할 수 있습니다. 프로토콜을 구현하는 호출 객체의 참조를 보유하는 위임 객체가 있습니다.

아래에 예가 나와 있습니다.

#import <Foundation/Foundation.h>

@protocol PrintProtocolDelegate
- (void)processCompleted;

@end

@interface PrintClass :NSObject {
   id delegate;
}

- (void) printDetails;
- (void) setDelegate:(id)newDelegate;
@end

@implementation PrintClass
- (void)printDetails {
   NSLog(@"Printing Details");
   [delegate processCompleted];
}

- (void) setDelegate:(id)newDelegate {
   delegate = newDelegate;
}

@end

@interface SampleClass:NSObject<PrintProtocolDelegate>
- (void)startAction;

@end

@implementation SampleClass
- (void)startAction {
   PrintClass *printClass = [[PrintClass alloc]init];
   [printClass setDelegate:self];
   [printClass printDetails];
}

-(void)processCompleted {
   NSLog(@"Printing Process Completed");
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass startAction];
   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-22 21:15:50.362 Protocols[275:303] Printing Details
2013-09-22 21:15:50.364 Protocols[275:303] Printing Process Completed

위의 예에서 우리는 delgate 메소드가 어떻게 호출되고 실행되는지 보았습니다. startAction으로 시작하여 프로세스가 완료되면 프로세스가 완료되었음을 알리기 위해 대리자 메서드 processCompleted가 호출됩니다.

모든 iOS 또는 Mac 앱에서 델리게이트 없이는 프로그램을 구현할 수 없습니다. 따라서 대의원의 사용법을 이해하는 것이 중요합니다. 위임 개체는 메모리 누수를 방지하기 위해 unsafe_unretained 속성 유형을 사용해야합니다.

동적 바인딩은 컴파일 타임이 아닌 런타임에 호출 할 메서드를 결정합니다. 동적 바인딩은 후기 바인딩이라고도합니다.

Objective-C에서 모든 메서드는 런타임에 동적으로 확인됩니다. 실행되는 정확한 코드는 메서드 이름 (선택자)과 수신 객체 모두에 의해 결정됩니다.

동적 바인딩은 다형성을 가능하게합니다. 예를 들어 Rectangle 및 Square를 포함한 개체 모음을 고려하십시오. 각 개체에는 고유 한 printArea 메서드 구현이 있습니다.

다음 코드 조각에서 [anObject printArea] 표현식에 의해 실행되어야하는 실제 코드는 런타임에 결정됩니다. 런타임 시스템은 실행되는 메서드에 대한 선택기를 사용하여 anObject의 어떤 클래스에서든 적절한 메서드를 식별합니다.

동적 바인딩을 설명하는 간단한 코드를 살펴 보겠습니다.

#import <Foundation/Foundation.h>

@interface Square:NSObject {
   float area;
}

- (void)calculateAreaOfSide:(CGFloat)side;
- (void)printArea;
@end

@implementation Square
- (void)calculateAreaOfSide:(CGFloat)side {
   area = side * side;
}

- (void)printArea {
   NSLog(@"The area of square is %f",area);
}

@end

@interface Rectangle:NSObject {
   float area;
}

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth;
- (void)printArea;
@end

@implementation  Rectangle

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth {
   area = length * breadth;
}

- (void)printArea {
   NSLog(@"The area of Rectangle is %f",area);
}

@end

int main() {
   Square *square = [[Square alloc]init];
   [square calculateAreaOfSide:10.0];
   
   Rectangle *rectangle = [[Rectangle alloc]init];
   [rectangle calculateAreaOfLength:10.0 andBreadth:5.0];
   
   NSArray *shapes = [[NSArray alloc]initWithObjects: square, rectangle,nil];
   id object1 = [shapes objectAtIndex:0];
   [object1 printArea];
   
   id object2 = [shapes objectAtIndex:1];
   [object2 printArea];
   
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-28 07:42:29.821 demo[4916] The area of square is 100.000000
2013-09-28 07:42:29.821 demo[4916] The area of Rectangle is 50.000000

위의 예에서 볼 수 있듯이 printArea 메서드는 런타임에 동적으로 선택됩니다. 동적 바인딩의 예이며 유사한 종류의 개체를 다룰 때 많은 상황에서 매우 유용합니다.

객체를 포함하는 클래스를 정의하는 클래스 클러스터 내에 하위 클래스를 만들 수 있습니다. 이러한 클래스 개체는 복합 개체입니다.

따라서 클래스 클러스터가 무엇인지 궁금 할 수 있습니다. 따라서 먼저 클래스 클러스터가 무엇인지 살펴 보겠습니다.

클래스 클러스터

클래스 클러스터는 Foundation 프레임 워크가 광범위하게 사용하는 디자인 패턴입니다. 클래스 클러스터는 공용 추상 슈퍼 클래스 아래에 여러 개인용 구체적인 하위 클래스를 그룹화합니다. 이러한 방식으로 클래스를 그룹화하면 기능적 풍부함을 줄이지 않고 객체 지향 프레임 워크의 공개적으로 볼 수있는 아키텍처가 단순화됩니다. 클래스 클러스터는 Abstract Factory 디자인 패턴을 기반으로합니다.

간단하게하기 위해 유사한 함수에 대해 여러 클래스를 만드는 대신 입력 값에 따라 처리를 처리하는 단일 클래스를 만듭니다.

예를 들어, NSNumber에는 char, int, bool 등과 같은 많은 클래스 클러스터가 있습니다. 우리는 그것들을 모두 단일 클래스에서 유사한 작업을 처리하는 단일 클래스로 그룹화합니다. NSNumber는 실제로 이러한 기본 유형의 값을 객체로 래핑합니다.

그렇다면 정확히 합성물이란 무엇일까요?

자체 디자인의 개체에 개인 클러스터 개체를 포함하여 복합 개체를 만듭니다. 이 복합 객체는 기본 기능을 위해 클러스터 객체에 의존 할 수 있으며 복합 객체가 특정 방식으로 처리하려는 메시지 만 가로 챌 수 있습니다. 이 아키텍처는 작성해야하는 코드의 양을 줄이고 Foundation Framework에서 제공하는 테스트 된 코드를 활용할 수 있도록합니다.

이것은 다음 그림에 설명되어 있습니다.

복합 객체는 자신을 클러스터의 추상 수퍼 클래스의 하위 클래스로 선언해야합니다. 서브 클래스로서 수퍼 클래스의 기본 메소드를 재정의해야합니다. 파생 메서드를 재정의 할 수도 있지만 파생 메서드가 기본 메서드를 통해 작동하므로 필요하지 않습니다.

NSArray 클래스의 count 메소드는 예입니다. 그것이 재정의하는 메서드의 중간 개체의 구현은 다음과 같이 간단 할 수 있습니다.

- (unsigned)count  {
   return [embeddedObject count];
}

위의 예에서 포함 된 객체는 실제로 NSArray 유형입니다.

복합 개체 예

이제 완전한 예제를보기 위해 아래에 제공된 Apple 문서의 예제를 살펴 보겠습니다.

#import <Foundation/Foundation.h>

@interface ValidatingArray : NSMutableArray {
   NSMutableArray *embeddedArray;
}

+ validatingArray;
- init;
- (unsigned)count;
- objectAtIndex:(unsigned)index;
- (void)addObject:object;
- (void)replaceObjectAtIndex:(unsigned)index withObject:object;
- (void)removeLastObject;
- (void)insertObject:object atIndex:(unsigned)index;
- (void)removeObjectAtIndex:(unsigned)index;

@end

@implementation ValidatingArray
- init {
   self = [super init];
   if (self) {
      embeddedArray = [[NSMutableArray allocWithZone:[self zone]] init];
   }
   return self;
}

+ validatingArray {
   return [[self alloc] init] ;
}

- (unsigned)count {
   return [embeddedArray count];
}

- objectAtIndex:(unsigned)index {
   return [embeddedArray objectAtIndex:index];
}

- (void)addObject:(id)object {
   if (object != nil) {
      [embeddedArray addObject:object];
   }
}

- (void)replaceObjectAtIndex:(unsigned)index withObject:(id)object; {
   if (index <[embeddedArray count] && object != nil) {
      [embeddedArray replaceObjectAtIndex:index withObject:object];
   }
}

- (void)removeLastObject; {
   if ([embeddedArray count] > 0) {
      [embeddedArray removeLastObject];
   }
}

- (void)insertObject:(id)object atIndex:(unsigned)index; {
   if (object != nil) {
      [embeddedArray insertObject:object atIndex:index];
   }
}

- (void)removeObjectAtIndex:(unsigned)index; {
   if (index <[embeddedArray count]) {
      [embeddedArray removeObjectAtIndex:index];
   }
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   ValidatingArray *validatingArray = [ValidatingArray validatingArray];
   
   [validatingArray addObject:@"Object1"];
   [validatingArray addObject:@"Object2"];
   [validatingArray addObject:[NSNull null]];
   [validatingArray removeObjectAtIndex:2];
   NSString *aString = [validatingArray objectAtIndex:1];
   NSLog(@"The value at Index 1 is %@",aString);
   [pool drain];
   
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-28 22:03:54.294 demo[6247] The value at Index 1 is Object2

위의 예에서 배열의 한 함수를 확인하면 정상적인 시나리오에서 충돌을 일으키는 null 개체를 추가 할 수 없음을 알 수 있습니다. 그러나 유효성 검사 배열이 처리합니다. 마찬가지로 배열 유효성 검사의 각 방법은 정상적인 작업 순서와는 별도로 유효성 검사 프로세스를 추가합니다.

Apple 문서를 참조하면 아래와 같이 Foundation 프레임 워크의 세부 정보를 볼 수 있습니다.

Foundation 프레임 워크는 Objective-C 클래스의 기본 계층을 정의합니다. 유용한 기본 객체 클래스 세트를 제공하는 것 외에도 Objective-C 언어에서 다루지 않는 기능을 정의하는 여러 패러다임을 도입합니다. 재단 프레임 워크는 이러한 목표를 염두에두고 설계되었습니다.

  • 작은 기본 유틸리티 클래스 세트를 제공하십시오.

  • 할당 해제와 같은 일에 일관된 규칙을 도입하여 소프트웨어 개발을 더 쉽게 만듭니다.

  • 유니 코드 문자열, 개체 지속성 및 개체 배포를 지원합니다.

  • 이식성을 향상시키기 위해 OS 독립 수준을 제공합니다.

프레임 워크는 Apple이 인수 한 NeXTStep에 의해 개발되었으며 이러한 기본 클래스는 Mac OS X 및 iOS의 일부가되었습니다.

NeXTStep에서 개발 되었기 때문에 "NS"라는 클래스 접두사가 있습니다.

우리는 모든 샘플 프로그램에서 Foundation Framework를 사용했습니다. Foundation Framework를 사용하는 것은 거의 필수입니다.

일반적으로 우리는 다음과 같은 것을 사용합니다. #import <Foundation/NSString.h> Objective-C 클래스를 가져 오지만 너무 많은 클래스를 가져 오는 것을 방지하기 위해 모두 #import <Foundation/Foundation.h>.

NSObject는 기초 키트 클래스를 포함한 모든 개체의 기본 클래스입니다. 메모리 관리 방법을 제공합니다. 또한 런타임 시스템에 대한 기본 인터페이스와 Objective-C 개체로 작동하는 기능을 제공합니다. 기본 클래스가 없으며 모든 클래스의 루트입니다.

기능에 기반한 기초 수업

Sr. 아니. 루프 유형 및 설명
1 데이터 저장고

NSArray, NSDictionary 및 NSSet은 모든 클래스의 Objective-C 객체를위한 스토리지를 제공합니다.

2 텍스트 및 문자열

NSCharacterSet은 NSString 및 NSScanner 클래스에서 사용하는 다양한 문자 그룹을 나타냅니다. NSString 클래스는 텍스트 문자열을 나타내며 문자열 검색, 결합 및 비교를위한 메서드를 제공합니다. NSScanner 객체는 NSString 객체에서 숫자와 단어를 스캔하는 데 사용됩니다.

날짜와 시간

NSDate, NSTimeZone 및 NSCalendar 클래스는 시간과 날짜를 저장하고 달력 정보를 나타냅니다. 날짜 및 시간 차이를 계산하는 방법을 제공합니다. NSLocale과 함께 다양한 형식으로 날짜와 시간을 표시하고 세계의 위치에 따라 시간과 날짜를 조정하는 방법을 제공합니다.

4 예외 처리

예외 처리는 예기치 않은 상황을 처리하는 데 사용되며 NSException과 함께 Objective-C에서 제공됩니다.

5 파일 처리

파일 처리는 NSFileManager 클래스의 도움으로 수행됩니다.

6 URL 로딩 시스템

일반적인 인터넷 프로토콜에 대한 액세스를 제공하는 클래스 및 프로토콜 집합입니다.

빠른 열거는 컬렉션을 통해 열거하는 데 도움이되는 Objective-C의 기능입니다. 따라서 빠른 열거에 대해 알기 위해서는 다음 섹션에서 설명 할 컬렉션에 대해 먼저 알아야합니다.

Objective-C의 컬렉션

컬렉션은 기본 구조입니다. 다른 개체를 보관하고 관리하는 데 사용됩니다. 컬렉션의 전체 목적은 개체를 효율적으로 저장하고 검색하는 일반적인 방법을 제공하는 것입니다.

컬렉션에는 여러 가지 유형이 있습니다. 그들은 모두 다른 물체를 잡을 수 있다는 동일한 목적을 수행하지만, 대부분 물체를 회수하는 방식이 다릅니다. Objective-C에서 사용되는 가장 일반적인 컬렉션은 다음과 같습니다.

  • NSSet
  • NSArray
  • NSDictionary
  • NSMutableSet
  • NSMutableArray
  • NSMutableDictionary

이러한 구조에 대해 자세히 알고 싶다면 Foundation Framework의 데이터 저장소를 참조하십시오 .

빠른 열거 구문

for (classType variable in collectionObject ) { 
  statements 
}

다음은 빠른 열거의 예입니다.

#import <Foundation/Foundation.h>

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSArray *array = [[NSArray alloc]
   initWithObjects:@"string1", @"string2",@"string3",nil];
   
   for(NSString *aString in array) {
      NSLog(@"Value: %@",aString);
   }
   
   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-28 06:26:22.835 demo[7426] Value: string1
2013-09-28 06:26:22.836 demo[7426] Value: string2
2013-09-28 06:26:22.836 demo[7426] Value: string3

출력에서 볼 수 있듯이 배열의 각 객체는 순서대로 인쇄됩니다.

뒤로 빠른 열거

for (classType variable in [collectionObject reverseObjectEnumerator] ) { 
  statements 
}

다음은 빠른 열거에서 reverseObjectEnumerator에 대한 예입니다.

#import <Foundation/Foundation.h>

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSArray *array = [[NSArray alloc]
   initWithObjects:@"string1", @"string2",@"string3",nil];
   
   for(NSString *aString in [array reverseObjectEnumerator]) {
      NSLog(@"Value: %@",aString);
   }
   
   [pool drain];
   return 0;
}

이제 프로그램을 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

2013-09-28 06:27:51.025 demo[12742] Value: string3
2013-09-28 06:27:51.025 demo[12742] Value: string2
2013-09-28 06:27:51.025 demo[12742] Value: string1

출력에서 볼 수 있듯이 배열의 각 개체가 인쇄되지만 일반적인 빠른 열거와 비교하면 역순으로 인쇄됩니다.

메모리 관리는 모든 프로그래밍 언어에서 가장 중요한 프로세스 중 하나입니다. 객체의 메모리가 필요할 때 할당되고 더 이상 필요하지 않을 때 할당 해제되는 프로세스입니다.

개체 메모리 관리는 성능의 문제입니다. 응용 프로그램이 불필요한 개체를 해제하지 않으면 메모리 공간이 증가하고 성능이 저하됩니다.

Objective-C 메모리 관리 기술은 크게 두 가지 유형으로 분류 할 수 있습니다.

  • "수동 유지 해제"또는 MRR
  • "자동 참조 계수"또는 ARC

"수동 유지 해제"또는 MRR

MRR에서 우리는 자체적으로 객체를 추적하여 메모리를 명시 적으로 관리합니다. 이는 Foundation 클래스 NSObject가 런타임 환경과 함께 제공하는 참조 카운팅이라는 모델을 사용하여 구현됩니다.

MRR과 ARC의 유일한 차이점은 전자에서는 유지 및 해제가 수동으로 처리되고 후자는 자동으로 처리된다는 것입니다.

다음 그림은 Objective-C에서 메모리 관리가 작동하는 방식의 예를 나타냅니다.

Class A 객체의 메모리 수명주기는 위 그림에 나와 있습니다. 보시다시피 유지 횟수는 개체 아래에 표시되며 개체의 유지 횟수가 0이되면 개체가 완전히 해제되고 다른 개체가 사용할 수 있도록 해당 메모리가 할당 해제됩니다.

Class A 객체는 NSObject에서 사용할 수있는 alloc / init 메소드를 사용하여 먼저 생성됩니다. 이제 보유 횟수는 1이됩니다.

이제 클래스 B는 클래스 A의 개체를 유지하고 클래스 A의 개체의 유지 수는 2가됩니다.

그런 다음 클래스 C는 개체의 복사본을 만듭니다. 이제 인스턴스 변수에 대해 동일한 값을 가진 클래스 A의 다른 인스턴스로 생성됩니다. 여기에서 유지 횟수는 1이며 원래 개체의 유지 횟수가 아닙니다. 이것은 그림에서 점선으로 표시됩니다.

복사 된 객체는 release 메서드를 사용하여 Class C에 의해 해제되고 보유 횟수가 0이되므로 객체가 파괴됩니다.

초기 Class A Object의 경우 보유 횟수는 2이며, 파괴되기 위해서는 두 번 해제되어야합니다. 이는 보유 수를 각각 1과 0으로 감소시키는 클래스 A 및 클래스 B의 릴리스 문에 의해 수행됩니다. 마지막으로 객체가 파괴됩니다.

MRR 기본 규칙

  • 우리가 만든 모든 객체를 소유합니다. 이름이 "alloc", "new", "copy"또는 "mutableCopy"로 시작하는 메서드를 사용하여 객체를 만듭니다.

  • 보유를 사용하여 객체의 소유권을 얻을 수 있습니다. 수신 된 객체는 일반적으로 수신 된 메소드 내에서 유효하게 유지되며 해당 메소드는 해당 객체를 호출자에게 안전하게 반환 할 수도 있습니다. 두 가지 상황에서 리 테인을 사용합니다.

    • 접근 자 메서드 또는 init 메서드의 구현에서 속성 값으로 저장하려는 객체의 소유권을 가져옵니다.

    • 객체가 다른 작업의 부작용으로 무효화되는 것을 방지합니다.

  • 더 이상 필요하지 않으면 우리가 소유 한 객체의 소유권을 포기해야합니다. 릴리즈 메시지 나 자동 릴리즈 메시지를 보내 객체의 소유권을 포기해야합니다. 따라서 Cocoa 용어에서 객체의 소유권을 포기하는 것은 일반적으로 객체를 "해제"라고합니다.

  • 소유하지 않은 객체의 소유권을 포기해서는 안됩니다. 이것은 명시 적으로 언급 된 이전 정책 규칙의 결과 일뿐입니다.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass
- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

- (void)dealloc  {
  NSLog(@"Object deallocated");
  [super dealloc];
}

@end

int main() {
   
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   
   NSLog(@"Retain Count after initial allocation: %d", 
   [sampleClass retainCount]);
   [sampleClass retain];
   
   NSLog(@"Retain Count after retain: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"Retain Count after release: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"SampleClass dealloc will be called before this");
   
   // Should set the object to nil
   sampleClass = nil;
   return 0;
}

위의 프로그램을 컴파일하면 다음과 같은 결과가 나옵니다.

2013-09-28 04:39:52.310 demo[8385] Hello, World!
2013-09-28 04:39:52.311 demo[8385] Retain Count after initial allocation: 1
2013-09-28 04:39:52.311 demo[8385] Retain Count after retain: 2
2013-09-28 04:39:52.311 demo[8385] Retain Count after release: 1
2013-09-28 04:39:52.311 demo[8385] Object deallocated
2013-09-28 04:39:52.311 demo[8385] SampleClass dealloc will be called before this

"자동 참조 계수"또는 ARC

자동 참조 계산 또는 ARC에서 시스템은 MRR과 동일한 참조 계산 시스템을 사용하지만 컴파일 타임에 적절한 메모리 관리 방법 호출을 삽입합니다. 새로운 프로젝트에 ARC를 사용하는 것이 좋습니다. ARC를 사용하는 경우 일부 상황에서는 유용 할 수 있지만 일반적으로이 문서에 설명 된 기본 구현을 이해할 필요가 없습니다. ARC에 대한 자세한 내용은 ARC 릴리스 노트로 전환을 참조하십시오 .

위에서 언급했듯이 ARC에서는 컴파일러에 의해 처리되므로 릴리스를 추가하고 메서드를 유지할 필요가 없습니다. 실제로 Objective-C의 기본 프로세스는 여전히 동일합니다. 내부적으로 유지 및 해제 작업을 사용하므로 개발자가 이러한 작업에 대해 걱정하지 않고 쉽게 코딩 할 수 있으므로 작성되는 코드의 양과 메모리 누수 가능성이 모두 줄어 듭니다.

MRR과 함께 Mac OS-X에서 사용되는 가비지 콜렉션이라는 또 다른 원칙이 있었지만 OS-X Mountain Lion에서 폐기 된 이후 MRR과 함께 논의되지 않았습니다. 또한 iOS 개체에는 가비지 수집 기능이 없었습니다. 그리고 ARC를 사용하면 OS-X에서도 가비지 콜렉션을 사용하지 않습니다.

다음은 간단한 ARC 예입니다. ARC를 지원하지 않기 때문에 온라인 컴파일러에서는 작동하지 않습니다.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass
- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

- (void)dealloc  {
  NSLog(@"Object deallocated");
}

@end

int main() {
   /* my first program in Objective-C */
   @autoreleasepool {
      SampleClass *sampleClass = [[SampleClass alloc]init];
      [sampleClass sampleMethod];
      sampleClass = nil;
   }
   return 0;
}

위의 프로그램을 컴파일하면 다음과 같은 결과가 나옵니다.

2013-09-28 04:45:47.310 demo[8385] Hello, World!
2013-09-28 04:45:47.311 demo[8385] Object deallocated