1.6.4 어플리케이션 다듬기
이번에는 이전에 만들어 놓은 SimpleViewer에 스크롤을 추가하고, 아이콘을 변경하고, 몇 가지 세부사항을 변경하는 작업을 해보겠습니다.

1) 스크롤 추가

인터페이스 빌더에서 윈도우를  선택하고 메뉴에서 아래와 같이  Layout/Make Subviews of/ScrollView를 클릭합니다.
사용자 삽입 이미지

사용자 삽입 이미지
위와 같이 하면 ImgView 우측과 하단에 좌측과 같이 여백이 생기는 것을 확인하실 수 있습니다.










ImgView와 NSScrollView의  인스펙트를 오픈 해  Size의 Autosizing 항목을 각각 아래와 같이 변경해 줍니다. NSScrollView는 우측 하단 모서리 부분을 클릭하면 선택됩니다. 인스펙터 창의 상단 타이틀에서 현재 선택된 항목을 확인 합니다.
사용자 삽입 이미지 사용자 삽입 이미지

2) 메뉴 타이틀 변경

사용자 삽입 이미지
SimpleViewer를 실행 시키고 메뉴를 보면 좌측과 같이
About NewApplication
Hide NewApplication
Quit NewApplication
과 같이 어플리케이션 이름이 아니라 인스펙트 빌더의 기본값인 NewApplication으로 되어 있습니다.



사용자 삽입 이미지
인스펙터 빌더에서 MainMenu.nib에서 각각의 항목을 더블클릭 해 좌측과 같이 모든 NewApplication을 SimpleViwer로 변경합니다.

Nib 파일은 실행시 로드되기 때문에 컴파일 없이 인스펙터 빌더에서 저장하고 어플리케이션을 실해 하여 확인해 봅니다.





3) About SimpleViewer 판넬 변경

사용자 삽입 이미지
어플리케이션을 실행 시키고, 메뉴에서 About SimpleViewer를 클릭하면 좌측과 같은 판넬을 볼 수 있습니다.

__MyCompanyName__으로 되어 있는 부분과 버젼을 변경해 보겠습니다.





사용자 삽입 이미지
Xcode에서 좌측과 같이 Resources 그룹에서 info.plist를 에디터에서 오픈합니다.

하단을 보면 아래와 같이 CFBundelVersion 키에서 string으로 되어 있는 부분에 1.0으로 되어 있는 값을 원하는 버젼으로 수정합니다.

    <key>CFBundleVersion</key>
    <string>0.9</string>



이제는 그 밑의 infoPlist.strings를 열어 NSHumanReadableCopyright 부분을 원하는 저작권자 명으로 변경하여 줍니다.

NSHumanReadableCopyright = "© cocoadev.tistory.com, 2007";

이제 다시 프로그램을 실행시키고 메뉴에서 About을 클릭하면 아래와 같이 변경된 사항을 확인할 수 있습니다.
사용자 삽입 이미지


4) 아이콘 변경

사용자 삽입 이미지
프로그램을 실행해서 하단의 독을 보거나,  폴더에서 실행파일의 아이콘을 보면 좌측과 같이 맥의 기본 응용프로그램 아이콘으로 되어 있습니다.

이번에는 이 아이콘을 변경해 보겠습니다.

/Developer/Applications/Utilities에서 Icon Composer를 실행합니다.
사용자 삽입 이미지
좌측과 같이 Image RGB/Alpha의 각각의 사각형 영역에  원하는 이미지 파일을 드래그해서 가져다 놓습니다.

저는 128X128 JPG 이미지를 하나 만들어 Thumbnail(128X128) 영역에 드래그 해 놓고, 그 부분을 위로 계속 드래그 시켜 항목을 채웠습니다.

이제 메뉴에서 아이콘을 적당한 이름으로 저장합니다.





사용자 삽입 이미지
위에서 저장한 아이콘 파일(*.icns)을 Xcode 좌측 메뉴에서 Resources 그룹에 드래그 해서 가져다 놓으면 좌측과 같은 창이 나옵니다.

상단의  Copy items into destination group's folder(if needed) 항목의 체크를 확인하고 add 버튼을 클릭합니다.





이제 이전에 열었던 info.plist를 열어 CFBundleIconFile 항목을 아래와 같이 설정합니다.
    <key>CFBundleIconFile</key>
    <string>simpleviewer</string>
저는 아이콘 파일명을 simpleviewer.icns로 만들었습니다. 이전에 저장한 icns를 제외한 파일명을 입력해 줍니다.

이제 어플리케이션을 실행하여 About 메뉴를 클릭하면,  아래와 같이 변경된 내역을 확인할 수 있습니다.
사용자 삽입 이미지




AND

1.6.0 프로젝트 개요
JPG, GIF등의 이미지 파일을 NSImage를 이용하여 화면에 출력하고 , 확대 축소를 해주는 간단한 이미지 뷰어 프로그램을 만들어 보겠습니다.
사용자 삽입 이미지

1.6.1 프로젝트 생성
이전 포스트에서 경험 해 본 코코아 프로젝트와 소스파일을 생성하고, 인터페이스 빌더와 연결 할 수 있다는 전제 하에 설명하겠습니다. 이 부분에 이해가 안되시면 1.2와 1.3 포스트를 해보시고 오시기 바랍니다.

Xcode를 실행하고 아래와 같이 SimpleDraw 코코아 프로젝트를 생성합니다.
  1. 메뉴바에서 File/New Project...를 선택합니다.
  2. Application/Cocoa Application을 선택합니다.
  3. project Name에 SimpleViewer를 입력하고 finish 버튼을 클릭합니다.

1.6.2 인터페이스 빌더에서 작업

1) 서브 클래스 생성

Nib 파일을 클릭하여 인터페이스빌더를 열고 NSView 클래스의 서브클래스를 만들고(아래의 창에서 NSView에 마우스 우클릭 하여 Subclass NSView 클릭) 이름을 ImgView로 변경합니다.
사용자 삽입 이미지

위와 같은 방법으로 AppController란 NSObject의 서브클래스를 만듭니다. 서브클래스를 만든 후에 AppController를 우클릭하여 나오는 메뉴에서 Instantiate AppController를 클릭하여 인스턴스를 생성합니다.
사용자 삽입 이미지


2) 컨트롤 생성 및 속성 설정

윈도우를 열고 팔레트의 Containers 항목에서  CustomeView와 Controls 항목에서 Slider를 드래그해서 아래와 같이 윈도우에 배치 합니다.

CutomeView를 클릭 후에 인스펙터(command+5)를 불러 내어 Custom Class 항목에서, 이전에 만들어 놓은 ImgView를 선택하고 아래와 같이 CustomeView가 ImgView로 변경됨을 확인합니다.
사용자 삽입 이미지

Size 항목에서 하단의 Autosizing 항목에서 아래와 같이 사각형내의 선들을  마우스로 클릭하여 스프링처럼 나오게 만듭니다. 이 작업은 윈도우의 크기가 변경될 때 상하좌우 크기가 윈도우에 맞게 자동으로 변경되게 합니다.
사용자 삽입 이미지

슬라이더의 속성을 아래와 같이 설정 합니다. Minimum은 최소값, Maximum은 최대값, Current는 현재값, Number of Markers는 슬라이더 상단의 눈금의 갯수를 의미합니다.
사용자 삽입 이미지

슬라이더도 윈도우의 크기에 맞추어 변경되게 하기위해, 아래와 같이 Size 항목에서 하단의 Autosizing의 사각형 내부의 좌우선을 클릭하여 스프링이 되게 만듭니다. 이 작업은 슬라이더의 높이는 유지하며 너비가 윈도우의 크기와 함께 변하도록 만들어 줍니다.
사용자 삽입 이미지

3) 연결

사용자 삽입 이미지
인터페이스 빌더의 Instances항목에서 AppController의 인스펙터를 불러내어 imgView 아울렛을 추가하고, Type을 ImgView로 선택합니다.

인스펙터는 항목을 마우스로 클릭하여 포커스를 준 후에 shift+command+i 또는 commad+숫자 를 입력하여 불러낼 수 있습니다.

이 작업은 AppController에서 ImgView를 제어할 수 있도록 합니다.










사용자 삽입 이미지
이제 Actions 항목을 선택하고 resizeImage와 openImage 액션을 추가합니다.

resizeImage는 하단의 슬라이더가 변경될 때, 이미지 크기를 변경하고, openImage는 메뉴에서 파일을 오픈할 때 처리하기 위한 액션입니다.




control 키를 누른 상태에서 AppController를 드래그하여  ImgView에 놓습니다. 아래와 같이 AppControll의 ImgView 아울렛에 연결(connect 버튼을 클릭 후, 원모양 아이콘을 확인)합니다.
사용자 삽입 이미지

control 키를 누른 상태에서 슬라이더를 드래그하여 AppController에 놓습니다. Taget/Action에서 resizeImage에 연결합니다.
사용자 삽입 이미지

아래와 같이 메인메뉴의 File에서 오픈을 control 키를 누른 상태에서 드래그하여 AppController에 놓습니다. Target/Action에서 openImage에 연결합니다. 이 작업으로 사용자가 메뉴에서 Open을 클릭하면 AppController의 openImage를 호출합니다.
사용자 삽입 이미지

이제 인스펙트빌더에서 1차적인 작업이 완료되었습니다. Classes에서 AppController와 ImgView를 각각 우클릭하여 CreateFiles  for AppController(and Img View)를 선택하여 소스파일을 생성하고 Xcode로 돌아 갑니다.


1.6.3 소스코드 수정
1) AppController.h 수정

인터페이스 빌더에서의 작업으로 헤더파일에서 해야 할 작업은 거의 없습니다. 다만 컴파일 시 오류를 막기 위해 아래와 같이 @class ImgView; 란 라인을 추가합니다.
#import <Cocoa/Cocoa.h>

@class ImgView;

@interface AppController : NSObject
{
    IBOutlet ImgView *imgView;
}
- (IBAction)openImage:(id)sender;
- (IBAction)resizeImage:(id)sender;
@end


2) AppController.m 수정

#import "AppController.h"
#import "ImgView.h"

@implementation AppController

- (void)openPanelDidEnd:(NSOpenPanel *)openPanel
             returnCode:(int)returnCode
            contextInfo:(void *)x
{   
    NSString *path;
    NSImage *image;
   
    if (returnCode == NSOKButton) {
        path = [openPanel filename];
   
        NSImageRep *imgRep = [NSImageRep imageRepWithContentsOfFile:path];
        NSSize frameSize = [imgRep size];
       
        image = [[NSImage alloc] initWithContentsOfFile:path];
       
        [imgView setImage:image];
        [imgView setFrameSize:frameSize];
        [image release];
    }
}

- (IBAction)openImage:(id)sender
{
    NSOpenPanel *panel = [NSOpenPanel openPanel];
   
    [panel beginSheetForDirectory:nil
                             file:nil
                            types:[NSImage imageFileTypes]
                   modalForWindow:[imgView window]
                    modalDelegate:self
                   didEndSelector:
        @selector(openPanelDidEnd:returnCode:contextInfo:)
                      contextInfo:NULL];
}

- (IBAction)resizeImage:(id)sender
{
    [imgView setRatio:[sender floatValue]];
}

@end

#import "ImgView.h"
ImgView 클래스를 사용하기 때문에 위와 같이 ImgView.h를 인클루드 시킵니다.

아래의 메소드는 파일 오픈을 클릭하였을 경우, 파일선택 창에서 파일 선택이 완료 된 후에 불리어 지는 콜백 함수입니다. 이 메소는 파일오픈 판넬을 오픈할 때 등록하여 주며, 나중에 다시 설명하겠습니다.
- (void)openPanelDidEnd:(NSOpenPanel *)openPanel
             returnCode:(int)returnCode
            contextInfo:(void *)x
{   
    NSString *path;
    NSImage *image;

사용자가 파일 창에서 [열기] 버튼을 클릭하였을 경우에만 실행되도록 합니다.  
    if (returnCode == NSOKButton) {
        path = [openPanel filename];
   
파일 원본 크기를 알기 위해 NSImageRep 오브젝트를 사용합니다.
        NSImageRep *imgRep = [NSImageRep imageRepWithContentsOfFile:path];
        NSSize frameSize = [imgRep size];
     
NSImage에 이미지 파일을 등록합니다.  
        image = [[NSImage alloc] initWithContentsOfFile:path];
       
imgView에 이미지를 설정하고, imgView의 크기를 이미지의 원본크기로 변경합니다.
        [imgView setImage:image];
        [imgView setFrameSize:frameSize];
        [image release];
    }
}

다음은 사용자가 파일오픈을 선택하였을 때 호출되는 - (IBAction)openImage:(id)sender 메소드에서 파일선택 판넬을 오픈하기 위해 아래와 같이 추가합니다.
    NSOpenPanel *panel = [NSOpenPanel openPanel];
   
    [panel beginSheetForDirectory:nil
                             file:nil
                            types:[NSImage imageFileTypes]
                   modalForWindow:[imgView window]
                    modalDelegate:self
                   didEndSelector:
        @selector(openPanelDidEnd:returnCode:contextInfo:)
                      contextInfo:NULL];
모달(판넬이 떠있을 때는 닫기전에는 소유 윈도우는 제어되지 않습니다)로 뛰우며 선택 가능한 파일 종류, 소유 윈도우, 콜백함수를 설정합니다.

@selector(openPanelDidEnd:returnCode:contextInfo:) 이 부분에서 파일선택이 완료되면 위에서 작성한 openPanelDidEnd 메소드가 호출되도록 하여 줍니다.

[imgView setRatio:[sender floatValue]];
슬라이더가 변경되면 호출되는 resizeImage 메소드에서 imgView가 크기를 변경하도록 setRatio를 호출합니다. 이 메소드는 다음 ImgView 클랙스에서 작성되어질 것 입니다.

3) ImgView.h 수정

#import <Cocoa/Cocoa.h>

@interface ImgView : NSView
{
    NSImage *image;
    NSSize orgSize;
    float ratio;
}

- (void)setImage:(NSImage *)img;
- (void)setRatio:(float)r;

@end

NSImage *image;

이미지 출력을 위해 NSImage 클래스를 선언 합니다.

NSSize orgSize;

이미지의 원본 크기를 저장합니다.

float ratio;
이미지 확대/축소 비율을 저장합니다. 0이 최소, 20이 최대, 10이 원본크기를 출력합니다.

- (void)setImage:(NSImage *)img;
선택된 이미지를 image에 설정하는 메소드입니다. 파일메뉴에서 파일 선택 시 AppController에서 호출합니다.

- (void)setRatio:(float)r;
확대/축소 비율을 설정합니다. 슬라이더 변경 시 AppController에서 호출합니다.

4) ImgView.m 수정

#import "ImgView.h"

@implementation ImgView

- (id)initWithFrame:(NSRect)frameRect
{
    if ((self = [super initWithFrame:frameRect]) != nil) {
        // Add initialization code here
        ratio = 10;
    }
    return self;
}

- (void)drawRect:(NSRect)rect
{
    [[NSColor whiteColor] set];
    [NSBezierPath fillRect:rect];
   
    if(image) {
        NSRect imgRect;
        NSRect drawRect;
       
        if(ratio != 0.0f) {
            imgRect.origin = NSZeroPoint;
            imgRect.size = orgSize;
       
            drawRect = [self bounds];
       
            NSLog(@"drawRect: %f, %f", drawRect.size.width, drawRect.size.height);
           
            [image drawInRect:drawRect
                     fromRect:imgRect
                    operation:NSCompositeSourceOver
                     fraction:1.0];
        }   
    }
}

- (void)setImage:(NSImage *)img
{
    [img retain];
    [image release];
   
    image = img;
   
    orgSize = [image size];
   
    [self setNeedsDisplay:YES];
}

- (void)setRatio:(float)r
{
    NSSize viewSize;
    ratio = r;
   
    NSLog(@"RATIO: %f", ratio);
   
    viewSize.width = (orgSize.width * ratio)/10;
    viewSize.height = (orgSize.height * ratio)/10;
   
    [self setFrameSize:viewSize];
    [self setNeedsDisplay:YES];
}

- (void) dealloc
{
    [image release];
    [super dealloc];
}

@end

ratio = 10;
initWithFrame는 ImgView가 초기화될 때, 자동으로 호출되는 메소드 입니다. 이곳에서 초기 오브젝트를 생성하거나 변수를 초기화 합니다. 이미지 선택시 원본 크기로 보이게 하기 위해 ratio를 10으로 설정합니다.

다음은 drawRect 메소드 내에 아래의 라인을 추가합니다. drawRect는 ImgView가 그려져야 할 필요가 있을 때 자동으로 불려지는 메소드 입니다. 이곳에서 그려질 내용들을 처리 합니다.

[[NSColor whiteColor] set];
[NSBezierPath fillRect:rect];
배경색을 흰색으로 채웁니다.

이미지 오브젝트가 설정되었을 때만 출력합니다.
    if(image) {
        NSRect imgRect;
        NSRect drawRect;

확대비율이 0일때는 출력하지 않습니다.  
        if(ratio != 0.0f) {
            imgRect.origin = NSZeroPoint;
            imgRect.size = orgSize;
       
            drawRect = [self bounds];

이미지를 출력합니다.  
            [image drawInRect:drawRect
                     fromRect:imgRect
                    operation:NSCompositeSourceOver
                     fraction:1.0];
        }   
    }
}

아래의 setImgae에서는 사용자가 선택한 파일을 image에 설정합니다.
- (void)setImage:(NSImage *)img
{
    [img retain];
    [image release];
 
image를 설정하고 원본 사이즈의 크기를 저장합니다.
    image = img;
    orgSize = [image size];
다시 그려지도록 알려주며, 이 위의 drawRect가 호출됩니다.  
    [self setNeedsDisplay:YES];
}

아래의 setRatio에서는 사용자가 슬라이더의 변경시에, 크기를 변경해 주는 작업을 합니다.
- (void)setRatio:(float)r
{
    NSSize viewSize;
    ratio = r;

10을 원본 크기로 비율에 맞게 크기를 조절합니다.  
    viewSize.width = (orgSize.width * ratio)/10;
    viewSize.height = (orgSize.height * ratio)/10;

ImgView의 크기를 현재 배율에 맞게 변경합니다.  
    [self setFrameSize:viewSize];
다시 그려지도록 알려주며, 이 위의 drawRect가 호출됩니다.
    [self setNeedsDisplay:YES];
}

메모리에서 해제합니다.
- (void) dealloc
{
    [image release];
    [super dealloc];
}

이제 모든 변경사항을 저장하고 프로젝트를 빌드 후에, 이미지 파일을 선택하여 테스트 해봅니다. 이미지를 불러보고 윈도우의 크기를 변경해 봅니다. 아직 스크롤을 처리하지 않아 커다란 이미지는 제대로 보실 수 없을 것입니다. 이는 다음장에서 처리해 보겠습니다.

AND

Objective-C는 1980년대 Stepstone사의 Brad Cox와 Tom Love에 의해 기존의 C에 SmallTalk의 객체지향 장점을 추가하여 만들어진 멋진 언어라고 합니다. 하지만 주위에선 별로 사용자를 볼 수가 없습니다.

개발환경이 특정 하드웨어나 OS로 한정되어 있고, 가장 많은 사용자를 가진 윈도우즈용 어플리케이션을 제작할 수 없어서(제가 아는 한에서 이며, 확실치 않습니다.) 인 것 같습니다.

보기에도 언뜻 Objective-C 소스를 보면 C와는 상관없는 전혀 별개의 언어로 보여, C/C++ 사용자가 접근이 힘들어 보입니다. 이유는 C에다 클래스와 메시지 전달 방식의 메소드 등 추가된 문법 때문입니다.

하지만 이 부분은 쉽게 배울 수 있으며, 어디선가 C를 알고 객체지향 프로그램에 대한 이해가 있다면 2시간 이면 Object-C를 배울 수 있다는 내용을 본적이 있습니다. 저같이 C/C++을 잘하지 못하는 사람도 대충 배워 가는 것을 보면, 틀린 얘기는 아니라고 생각됩니다.

그래서 C/C++, 또는 윈도우즈에서 VC++을 사용해 보시고, Objective-C 경험이 전혀 없으신 분들을 위해 이 블로그의 제목처럼 맛만 보실 수 있도록 부실한 내용을 시작 하겠습니다.
 
우선 Xcode에서 cocoa application 프로젝트를 만들면, Xcode에서 자동으로 생성해주는 main.m를 확인해 보겠습니다. (만드는 방법은 튜토리얼 분류쪽의 포스트에 있습니다.)

우선 Objective-C에서는 헤더파일은 .h로 같은 이름을 사용하지만, 소스파일명에는 .c 대신에 .m 확장자를 사용함을 알 수 있습니다. 소스를 보겠습니다.

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])
{
    return NSApplicationMain(argc,  (const char **) argv);
}

MS처럼 윈도우로 넘어 오면서 C/C++ 고유의 main이란 이름을 가만히 놔두지 않는 것에 비하여, 전형적이고 친숙한 C의 main이 보입니다.

import만 생소하고 모두 C와 동일합니다. import는 Objective-C에서 추가된 전처리 명령어로 include와 유사하지만, 중복될 경우에는 한번만 include합니다. import대신 include의 사용도 가능합니다. 하지만 중복되어 인클루드될 경우를 대비해 헤더파일에
#ifndef _HEADER_NAME_H
#define _HEADER_NAME_H
.........
#endif  //_HEADER_NAME_H
과 같은 처리가 필요하지만 import를 사용하게 되면, 중복 오류를 신경 쓸 필요가 없습니다.

우선 테스트를 위해 아래와 같이 C코드를 추가하고 컴파일을 해봅니다.
void copy_str(char* des, char* src)
{
    strcpy(des, src);
}

int main(int argc, char *argv[])
{
    char buffer[12];
    char* ptr;
    
    copy_str(buffer, "Hellow!");
    ptr = buffer;
    
    printf("str: %s\n", ptr);
    
    return NSApplicationMain(argc,  (const char **) argv);
}

main을 봐도 알수 있듯이 C문법이 오류없이 컴파일 되며, 실행을 하게 되면 빈 윈도우와 함께 로그 윈도우에 str: Hello!를 출력합니다.

이 예를 들은 이유는 Objective-C가 C와 전혀 별개의 언어가 아닌 C언어의 확장으로 봐도 무방할 것 같습니다. 위에 언급한 바와 같이 C언어 또는 C++ 사용이 가능하면, 작은 노력으로도 쉽게 Objective-C를 사용할 수 있습니다.

이제 다른 소스를 확인해 보겠습니다. 아래는 Xcode에서 제공되는 샘플소스의 헤더 파일과 소스파일의 일부분입니다.

@interface DotView : NSView {
    float radius;
}
// Standard view create/free methods
- (id)initWithFrame:(NSRect)frame;
- (void)dealloc;
@end

#import <Cocoa/Cocoa.h>
#import "DotView.h"

@implementation DotView

- (void)mouseUp:(NSEvent *)event {
    NSPoint eventLocation = [event locationInWindow];
    center = [self convertPoint:eventLocation fromView:nil];
    [self setNeedsDisplay:YES];
}
@end

위에 테스트로 작성된 소스와는 다르게 객체를 사용하기 때문에, 전혀 C와는 관련 없는 소스로 보입니다.

C++이나 Java등을 사용하신 분들은 class의 선언과 구현인지 대충 짐작이 가시겠지만, C 문법이라고 보기엔 import, -, @, [], : 등 많은 부분이 눈에 거슬립니다. 아래에서 확연히 다른 점을 간단히 다루어 보겠습니다.

1) "@" 예약어

우선 "@"으로 시작되는 것은 Objective-C에서 추가된 예약어 입니다.

위에서 예를 보면 클래스의 선언부분은  @interface, @end로 구현부분은 @implementation, @end의 사이에 위치합니다.

또한 "hello"는 char* 형의 문자열을 의미하지만, @"hello"는 NSString에서 사용하는 문자열(참고로 @""는 아스키 코드만 가능하며, 한글은 UTF8로 처리해야 합니다.)을 의미하는 것과 같이 기존 C의 문법과 구별이 필요할 때에 사용한다고 보시면 됩니다..

2) 함수 선언

헤더파일을 보면 클래스의 메소드 선언 시 C++/Java와는 달리 클래스 선언 구역({})의 외부에서 선언 됩니다.

위의 - (id)initWithFrame:(NSRect)frame; 선언을 예로 들어 보겠습니다.

함수 앞에는 "-" 표시가 있는데 이는 인스턴스 메소드를 나타내며, "+"일 경우에는 클래스 메소드를 나타냅니다. "+"는 C++/Java의 static 맴버함수와 유사하여 인스턴스의 생성 없이 바로 사용할 수 있는 메소드입니다.

(id) 는 반환될 타입입니다. ()로 처리된다는 것만 제외하고 C와 동일합니다. 참고로 id는 모든 오브젝트를 가리키는 포인터입니다.

":"는 다음에 인자를 의미하며 인자가 ":(타입)이름"과 같이 나온다는 것을 의미합니다. 인자가 2개 이상일  경우에는 스페이스로 구분하며 아래와 같이 선언 합니다.

- (NSPoint)convertPoint:(NSPoint)aPoint fromView:(NSView *)aView;
보면 fromView라는 것이 혼돈을 주는데 인자의 별칭(alias)이라고 생각하시면 되고, 실제 호출 시에는 아래와 같이 사용합니다.

[self convertPoint:eventLocation fromView:nil];
이렇게 함으로써 소스코드는 길어 지지만, 메소드와 인자의 용도를 명확하게 합니다.

여기에는 없지만 변수앞에 사용하는 IBOutlet과 메소드에 사용하는 IBAction란 예약어가 있습니다. 이는 인터페이스 빌더에서 참조를 위한 것으로 변수와 메소드 타입에 영향을 주지 않습니다.  VC의 AFX_ 류로 생각하시면 됩니다.


3) 메소드 호출

center = [self convertPoint:eventLocation fromView:nil];
소스파일에 있는 위의 코드를 C++로 변경하면 아래와 같습니다.

center = this->convertPoint(eventLocation, NULL);

Objective-C에서는 메소드 호출(정확히는 메세지 전달)시 에는 [object method]의 형태로 사용됩니다. [object method:[object method]]와 같이 중첩해서 사용이 가능하며, 초기에는 혼돈이 오지만 자주 보면 object->method(object->method)와 같이 친숙해 집니다.


4) 프레임워크

라이브러리와 유사한 의미로 프레임워크라는 용어를 사용합니다. cocoa 프로젝트를 생성하면 Xcode 좌측의 Groups & Files에서 FrameWorks란 폴더를 찾을 수 있습니다.

 하단의 Other Frameworks를 보면 AppKit.framework와 Foundation.framework를 확인하실 수 있습니다. 이는 VC에서 MFC 클래스 라이브러리와 유사합니다.

Foundation은 NSObject, NSString, NSArray등의 기본적인 클래스들로 구성이 되어 있으며, AppKit은 NSWindow, NSButton, NSImage등 사용자 UI에 관련된 클래스들로 구성되어 있습니다.
 
사용자 삽입 이미지
좌측과 같이 이 두 framework 아래의 headers를 클릭해 보시면 cocoa 개발을 위한 기본적인 클래스 목록들을 확인하실 수 있습니다.






5) 기타

- Objective-C는 C++/Java와는 달리 class에 생성자/소멸자가 없지만, 이를 대치해서 사용할 수 있는 메소드와 이벤트가 있습니다.

- retain이라는 사용 카운터를 사용하여 오브젝트가 메모리에서 삭제되는 시기를 결정합니다. 인스턴스가 추가(alloc)되면 retain이 증가되고, 사용이 완료되면 release라는 메소드로 retain을 감소 합니다. retain이 0이 되면 삭제됩니다.

- Nib 파일 - NeXT Interface Builder의 약자로 오브젝트, 클래스, 리소스, 컨넥션, UI등의 정보와 파일을 가지고 있는 cocoa 어플리케이션에서는 매우 중요한 역활과 의미를 가지고 있는  파일 입니다.

이상으로 마치며... 프로그래밍 언어를 한번 정도 다루어 보신 분들, 특히 C++, Java라면 Objective-C는 쉽게 접근할 수 있는 언어입니다. C에 객체지향을 더했다는 측면에서, C++과 만들어진 이유와 나온 시기도 비슷하여 서로 비교해 보는 것도 재밌습니다. Cocoa와 MFC, VC++과 Xcode도 그렇고요.

앞으로 맥사용자들이 많이 늘어, C++ 사용자 처럼 Objective-C 사용자들이 많이 늘었으면 하는 바램입니다.
 

'Xcode 2 > Objective-C' 카테고리의 다른 글

Objective-C 코딩 스타일  (6) 2008.09.25
Objective-C class의 특징  (2) 2008.03.17
AND