[출처] - http://www.cocoadev.co.kr/94





흔히 사용되는 컨트롤들의 간단한 사용법을 알아 보겠습니다.
만들려는 예제의 모습은 좌측과 같습니다. 각 컨트롤들의 설정에 따라서 상단 텍스트 필드의 내용을 변경하여 보여주는 샘플을 작성해 보겠습니다.

이 예제를 따라 해보기 위해서는 인터페이스 빌더의 사용법과  인스턴스 생성, 인스턴스와의 연결 등에 관한 기본 내용을 알고 있어야 합니다. 잘 이해가지 않는 분들은 이전 포스트를 확인해 보신 후에 다시 보시기 바랍니다.



1. AppController 생성

XCode 에서 Cocoa Application으로 새로운 프로젝트를 생성합니다. 다시 New File에서 Objective-C Class를 선택한 후에 AppController란 이름으로 새로운 클래스를 생성합니다.

1) AppController.h 변경
이번 장에서 사용할 컨트롤들은 아래와 같습니다. 아래의 컨트롤들을 인터페이스 빌더에서 연결하기 위해 IBOutlet 변수들을 생성합니다.
NSTextField, NSTableView, NSMatrix, NSComboBox, NSColorWell, NSSlider, NSButton, NSProgressIndicator  

사용자의 조작으로 컨트롤의 상태가 변하는 알림 메시지를 받을 메소드를 생성합니다. 각 메소드는 아래와 같습니다.

- (IBAction)setDisplayText:(id)sender;
- (IBAction)adverbSelecterChanged:(id)sender;
- (IBAction)alignSliderChanged:(id)sender;
- (IBAction)notCheckerChanged:(id)sender;
- (IBAction)subjectMatrixChanged:(id)sender;
- (IBAction)colorWellChanged:(id)sender;

AppController.h
#import <Cocoa/Cocoa.h>

@interface AppController : NSObject {
    IBOutlet NSTextField* displayString;
    IBOutlet NSTableView* wordList;
    IBOutlet NSMatrix* subjectMatrix;
    IBOutlet NSComboBox* adverbSelecter;
    IBOutlet NSColorWell* colorWell;
    IBOutlet NSSlider* alignSlider;
    IBOutlet NSButton* notChecker;
    IBOutlet NSProgressIndicator* progressBar;   
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView;
- (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn
            row:(int)row;

- (IBAction)setDisplayText:(id)sender;
- (IBAction)adverbSelecterChanged:(id)sender;
- (IBAction)alignSliderChanged:(id)sender;
- (IBAction)notCheckerChanged:(id)sender;
- (IBAction)subjectMatrixChanged:(id)sender;
- (IBAction)colorWellChanged:(id)sender;

@end


2) AppController.m 변경

TableView는 좌측과 같이 테이블 형식으로 목록을 보여주는 컨트롤입니다. 각 셀에 데이터를 입력하기 위해서는 데이터를 등록하여 주는 dataSource를 지정해야 합니다.

여기서는  나중에 인터페이스 빌더에서 AppController를 dataSource로 등록하겠습니다. tableView의 dataSource가 되면 데이터를 요구하는 메시지에 응답하기 위해서 아래와 같은 두개의 메소드를 구현해야 합니다.

- (int)numberOfRowsInTableView:(NStableView *)tableView;
목록의 갯수를 반환합니다.

- (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row

각 셀의 데이터를 반환합니다. 이 반환된 값들로 각 셀들이 채워집니다. 셀에 데이터를 등록하는 것은 다음 포스팅에서 구현해 보겠습니다.

메시지를 처리하는 각 메소드들은 실제 기능을 구현하기 전에 정확히 동작하는지 확인하기 위해서 NSLog를 추가합니다. 소스파일 전체는 아래와 같습니다.

AppController.m
#import "AppController.h"

@implementation AppController

- (void)awakeFromNib
{
}

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

- (IBAction)setDisplayText:(id)sender
{
    NSLog(@"Button colicked");
}

- (IBAction)adverbSelecterChanged:(id)sender
{
    NSLog(@"adverbSelecter changed");
}

- (IBAction)alignSliderChanged:(id)sender
{
    NSLog(@"alignSlider Changed");
}

- (IBAction)notCheckerChanged:(id)sender
{
    NSLog(@"notChecker changed");
}

- (IBAction)subjectMatrixChanged:(id)sender
{
    NSLog(@"subject matix");
}

- (IBAction)colorWellChanged:(id)sender
{
    NSLog(@"colorWell changed");
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
    NSLog(@"tableView getRowCount");
    return 1;
}

- (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
    NSLog(@"tableView getColumnValue");
    return nil;
}

@end


2. 인터페이스 빌더에서 작업
 
1) 컨트롤 배치

윈도우에 각 컨트롤들이 배치되어야 할 모습은 아래와 같습니다.


팔레트에서 마우스 포인터를 해당 컨트롤 위에 놓으면 좌측의 빨간 화살표가 가르키는 것과 같이 컨트롤의 종류를 확인할 수 있습니다.

위의 이미지를 참조하여 팔레트에서 각각의 콘트롤들을 드래그로 가지고 와서 배치 합니다.





2) 속성 설정
각각의 콘트롤들의 속성을 변경합니다.

NSTextField
텍스트필드의 옵션을 좌측과 같이 설정합니다. 사용자의 입력은 받지 않기 때문에 Editable, Enabled를 해제합니다.


NSTableView
Attributes에서 Columns를 2로 설정합니다.
NSTableView를 더블클릭하면 좌측과 같이 푸른 테두리가  나타납니다. 이 상태에서 컬럼을 더블클릭하여 입력 모드로 변경되면 이름을 변경할 수 있습니다.

각각 목적어, 동사로 변경합니다.

NSMatrix
Rows 는 1 Cols는 2로 설정하고 Mode가 'Radio'로 되어 있음을 확인합니다.

NSComboBox
좌측과 같이 Visible Items를 4로 입력하고 4개의 항목을 추가합니다.

추가는 하단의 입력필드에서 이름을 입력 후에 [+] 버튼을 클릭합니다. 삭제는 아이템을 선택한 후에 [-]버튼을 클릭합니다.



NSColorWell
변 경없이 기본값을 유지합니다.

NSSlider
좌측과 같이 최소값을 0.0, 최대값을 100.0, 기본값을 50.0으로 설정합니다. 세단계만 선택되게 하기 위해 Number Of Markers를 3으로  Stop on ticks marks only를 체크 합니다.


NSButton
Type이  'CheckBox'로 되어 있음을 확인하고 Title에 '부정어로 만듭니다.'로 입력합니다.

NSProgressIndicator  
MinumRange 는 0.0, MaximumRange는 100.0으로 설정하고 Indeterminate를 체크 합니다.

2) AppControll 인스턴스 생성
AppController.h 를 인터페이스 빌더의 MainMenu.nib 윈도우로 드래그 해 놓습니다. Classes 항목에서 AppController를 우클릭하여 Instantiate AppController를 선택하여 인스턴스를 생성합니다.

이제 아래의 연결된 모습을 참조하여 윈도우의 각 항목들을 AppController의 IBOutlet 변수와 IBAction 메소드로 연결합니다.

각 컨트롤들은 아래의 AppController의 IBAction 메소드와 연결됩니다.
  • adverbSelecterChanged <- NSComboBox
  • alignSliderChanged <- NSSlider
  • notCheckerChanged <-NSButton (Check Box)
  • subjectMatrixChanged <- NSMatrix
  • colorWellChanged <- NSColorWell
  • setDisplayText <- NSButton (적용 Button)
 
마지막으로 위에 설명한 대로 좌측과 같이  TableView의 dataSource를 AppControll로 설정합니다.








이 제 컴파일 하고 실행한 후에 각각의 콘트롤의 값과 상태를 변경하여 봅니다. 그리고 RunLog 창에서 아래와 같이 메시지를 보내고 받는지 확인합니다.

잘 동작하지 않는 분들은 아래의 샘플 파일을 다운로드 받으신 후에 비교해 보시기 바랍니다.





이전 포스트에 이어서 프로그램을 완성해 보겠습니다. 이전의 소스에서 아래의 청색으 로 된 부분을 추가합니다.

1. AppController.h 수정

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject {
    NSMutableString *curString;
    NSString* dataArray[3][2];
   
    IBOutlet NSTextField* displayString;
    IBOutlet NSTableView* wordList;
    IBOutlet NSMatrix* subjectMatrix;
    IBOutlet NSComboBox* adverbSelecter;
    IBOutlet NSColorWell* colorWell;
    IBOutlet NSSlider* alignSlider;
    IBOutlet NSButton* notChecker;
    IBOutlet NSProgressIndicator* progressBar;   
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView;
- (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn
            row:(int)row;

- (IBAction)setDisplayText:(id)sender;
- (IBAction)adverbSelecterChanged:(id)sender;
- (IBAction)alignSliderChanged:(id)sender;
- (IBAction)notCheckerChanged:(id)sender;
- (IBAction)subjectMatrixChanged:(id)sender;
- (IBAction)colorWellChanged:(id)sender;
- (IBAction)wordListChanged:(id)sender;
@end


2. 인터페이스 빌더에서 수정

변경한 소스를 저장한 후에 변경된 사항을 인터페이스 빌더에 적용하기 위해서 다시 AppController.h 파일아이콘을 드래그 하여 인터페이스 빌더의 MainMenu.nib에 놓습니다.

좌측과 같이 윈도우의 TableView중에 목적어 컬럼을 선택합니다. 속성창을 열어 Identifier 항목을 1로 설정합니다.

이와 동일하게 동사 컬럼의 Identifier는 2로 설정합니다.




AppController에서 새로 추가한 메소드인 wordListChanged르 TableView에 연결합니다.

TableView를 선택하고 Control키를 클릭한 채 마우스로 드래그 하여 AppController 인스턴스에 가져다 놓습니다. 좌측의 속성 화면에서 wordListChanged를 선택하고 연결합니다.

(연결이 어려우신 분들은 이전 포스트를 참조하세요.)


3. AppController.m 수정

#import "AppController.h"

@implementation AppController

- (id)init
{
    self = [super init];
   
    curString = [[NSMutableString alloc] init];

    /* 목적어 데이터 설정 */

    dataArray[0][0] = [[NSString alloc] initWithUTF8String:"철수를"];
    dataArray[1][0] = [[NSString alloc] initWithUTF8String:"영희를"];
    dataArray[2][0] = [[NSString alloc] initWithUTF8String:"바둑이를"];
   
    /* 동사 데이터 설정 */
    dataArray[0][1] = [[NSString alloc] initWithUTF8String:"사랑했다"];

    dataArray[1][1] = [[NSString alloc] initWithUTF8String:"싫어했다"];
    dataArray[2][1] = [[NSString alloc] initWithUTF8String:"때렸다"];
   
    return self;
}

- (void)awakeFromNib
{
}

- (void)dealloc
{
    int i, j;
   
    /* 할당된 오브젝트 해제 */
    for(i = 0; i < 3; i++)
    {
        for(j = 0; j < 2; j++)
        {
            [dataArray[i][j] dealloc];
        }
    }
   
    [curString dealloc];
    [super dealloc];
}

- (IBAction)setDisplayText:(id)sender
{
    int pos = [wordList selectedRow]; // 테이블뷰에서 현재 선택된 열
    if(pos == -1) // 없으면 실행하지 않는다
        return;
   
    /** 조건에 따른 문자열 설정 */
    if([[subjectMatrix selectedCell] tag] == 0)
        [curString setString:[NSString stringWithUTF8String:"나는 "]];
    else
        [curString setString:[NSString stringWithUTF8String:"너는 "]];
   
    [curString appendString:dataArray[pos][0]];
    [curString appendString:@" "];
    [curString appendString: [adverbSelecter stringValue]];
       
    if([notChecker state] == NSOnState)
        [curString appendString:[NSString stringWithUTF8String:" 안 "]];
   
    [curString appendString:dataArray[pos][1]];
   
    /* 색상 설정 */
    [displayString setTextColor:[colorWell color]];
   
    /* 정렬 설정 */
    int align = [alignSlider intValue];

    if(align == 0)
        [displayString setAlignment:NSLeftTextAlignment];
    else if(align == 50)
        [displayString setAlignment:NSCenterTextAlignment];
    else
        [displayString setAlignment:NSRightTextAlignment];
   
    /* 텍스트 출력 */
    [displayString setStringValue:curString];
   
    /* 진행 상태바 에니메이션 중지 */
    [progressBar stopAnimation:self];

}

- (IBAction)adverbSelecterChanged:(id)sender
{
    /* 변경시 진행 상태바 에니메이션 시작 */
    [progressBar startAnimation:self];
}

- (IBAction)alignSliderChanged:(id)sender
{
    [progressBar startAnimation:self];
}

- (IBAction)notCheckerChanged:(id)sender
{
    [progressBar startAnimation:self];
}

- (IBAction)subjectMatrixChanged:(id)sender
{
    [progressBar startAnimation:self];
}

- (IBAction)colorWellChanged:(id)sender
{
    [progressBar startAnimation:self];
}

- (IBAction)wordListChanged:(id)sender
{
    [progressBar startAnimation:self];
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
    /* 테이블 열 갯수 3 반환 */
    return 3;

}

- (id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
    int pos;

    /** 현재 설정되어야 할 TableView의 컬럼을 반환한다. */
    if([[tableColumn identifier] characterAtIndex:0] == '1')
        pos = 0;
    else
        pos = 1;
   
    return dataArray[row][pos];
}

@end


이제 빌드를 하고 실행 하시면 좌측과 같이 어플리케이션이 실행됩니다. 각각의 옵션을 선택하고 [적용] 버튼을 클릭하면 선택된 옵션에 맞추어 상단에 텍스트가 출력됩니다.

옵션에 변동이 일어나면 하단의 바가 에니메이션되며 [적용] 버튼을 클릭하여 적용이 완료되면 진행 상태바의 에니메이션이 중지 됩니다.

전체 프로젝트 소스파일은 아래를 클릭해서 다운로드 받이스면 됩니다.











출처 : http://blog.naver.com/PostView.nhn?blogId=seogi1004&logNo=110085699616
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 8. 31. 11:43
Objective-C의 기본 문법을 정리했습니다.

원글Learn Objective-C by Scott Stevenson

작성자 블로그의 첫페이지에 있는 말.


All of the buildings, all of those cars were once just a dream in somebody's head. — Peter Gabriel
(모든 빌딩과 모든 자동차들도 원래는 누군가의 머리속의 꿈에 지나지 않았다.)


<순서>
 1.메소드의 호출
 2.접근자
 3.오브젝트의 생성
 4.기본 메모리 관리법
 5.클래스 Interface (.h)
 6.클래스 Implementation (.m)
 7.메모리 관리법 좀더 살펴보기
 8.로깅
 9.프로퍼티
10.Nil 오브젝트의 메소드 호출
11.카테고리


1.메소드의 호출 +-----+-----+-----+-----+-----+


기본 문법
[object method];
[object methodWithInput:input];


다른 언어에서 말하는 오브젝트명.메소드명 이 여기서는 [오브젝트 메소드] 괄호에 둘러쌓여있고 스페이스로 구분하는 형식이 된다.

파라메터를 가지는 경우에는 [오브젝트 메소드:파라매터] 로 불린다. (메소드와 파라매터사이에 콜론이 존재)

리턴값이 있는 경우
output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];


클래스 메소드도 같은 문법으로 호출 가능하다.
id myObject = [NSString string];


여기서 id란 myObject가 어떤 오브젝트의 참조도 될 수 있다는 뜻이며,
즉 컴파일 할 때에도 클래스 타입을 알지 못한다는 뜻이다.


하지만 여기선 딱 보면 NSString이란걸 알 수 있기에 아래와 같이도 쓸수 있다.
NSString* myString = [NSString string];


오브젝트 타입 옆에 *(아스타리스크)가 있는걸 볼 수 있다.
모든 Objective-c의 오브젝트 변수들은 포인터 타입이다.
id 타입은 이미 포인터 타입으로 정의 되어 있기 때문에 *(아스타리스크)를 붙일 필요가 없는것 뿐이다.


Nasted 메세지


일반적인 많은 프로그래밍 언어에서 Nasted 메소드나 함수를 호출할 때 아래와 같은 문법을 사용한다.
function1 ( function2() );


이것이 Objective-C에선 아래와 같이 표현된다.
[NSString stringWithFormat:[prefs format]];


다중 파라매터를 가지는 메소드 호출


이런 경우, Objective-C에서는 메소드 명을 여러 조각으로 나누어 사용한다.
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;


위의 메소드를 호출하는 방법은 아래와 같다.
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];


결국 이 말은 파라매터명이란 것이 존재 하지 않는 다는 뜻이며,
런타임 시스템에서 메소드 명은 writeToFile:atomically: 로 인식된다.

2.접근자 +-----+-----+-----+-----+-----+


Objective-c의 모든 인스턴스 변수들은 private이다. 즉 접근자를 사용하여 억세스 하여야 한다는 소리이다.


일반적인 문법


[photo setCaption:@"Day at the Beach"];
output = [photo caption];


두번째 줄의 코드는 인스턴스 변수를 직접 읽는다는 뜻이 아니라 caption이라는 메소드를 부르고 있는 것이다.
Objective-C에서는 일반적으로 getter 메소드에 get을 붙이지 않고 사용한다.


.(dot)를 이용한 문법


.(dot)는 접근자(getter and setter)를 위해 Objective-C 2.0에 새로 추가된 문법이다.


photo.caption = @"Day at the Beach";
output = photo.caption;


동일한 프로젝트 내에서는 한쪽 문법만 사용하는 것이 통일성 있게 코딩하는 방법이다.
또한 .(dot)는 일반 메소드 호출에는 사용할 수 없음을 명심하자.

3.오브젝트의 생성 +-----+-----+-----+-----+-----+


오브젝트를 생성하는 방법은 여러가지가 있다.


자동할당


NSString* myString = [NSString string];


자동으로 생성하여 할당해주는 편리한 방법이다. 자세한 내용은 나중에 살펴보도록 한다.
하지만 대부분의 오브젝트는 아래에 설명하는 수동 할당 방법을 사용하여야 한다.


수동할당


NSString* myString = [[NSString alloc] init];


이것은 메소드의 Nested된 호출방식이다.
우선 NSString클래스의 alloc메소드를 부른다.
이는 매우 하위레벨의 호출로써 메모리를 확보하고 오브젝트를 인스턴스화 한다.


다음으로 생성된 오브젝트의 init 메소드를 부른다.
init은 주로 초기화 작업을 하는데 예를 들면 내부 변수들의 인스턴스를 생성하는 작업 등이다.


값을 가지는 다른 버젼의 init을 호출하는 경우도 있다.


NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];

4.기본 메모리 관리법 +-----+-----+-----+-----+-----+


만약 Mac OS X에서 돌아가는 어플리케이션을 개발한다면 garbage collection을 사용할 수 있다.
다시 말하자면 복잡한 경우를 제외하고는 메모리 관리를 하지 않아도 된다는 뜻이다.


하지만 우리는 항상 garbage collection을 제공하는 환경하에서 작업하는 것이 아니기 때문에
기본 메모리 관리법을 알아 두도록 하자.


alloc을 이용하여 수동적으로 오브젝트를 생성하였을 경우에는 이를 release 하는 작업을 해야 한다.
반대로 자동으로 할당해주는 방법으로 생성한 오브젝트는 수동으로 release 하면 안된다.
이는 프로그램에 문제를 발생시킨다.


// string1 는 자동으로 release 될 것이다.
NSString* string1 = [NSString string];


// string2 는 사용이 끝난후 수동으로 release 해주어야 한다.
NSString* string2 = [[NSString alloc] init];
[string2 release];


여기서 string1 는 함수의 끝에서 자동으로 release된다고 생각하면 된다.


메모리 관리에 대해서 좀 더 알아둘 내용이 있지만
몇가지 다른 개념을 먼저 알고 가는 것이 좋음으로 뒤쪽에서 다시 보도록 한다.

5.클래스 Interface (.h) +-----+-----+-----+-----+-----+


Objective-C에서 클래스를 만드는 방법은 매우 간단하다.
.h 파일에 인터페이스를 적고 .m 파일에 내용을 적으면 된다.


.h 파일
인스턴스 변수와 퍼블릭 메소드의 인터페이스를 정의한다.


.m 파일
.h 에 정의한 인터페이스들을 implement한다.
그리고 private 메소드 들도 여기에 적어준다.


<.h 파일의 예>
#import

@interface Photo : NSObject {
    NSString* caption;
    NSString* photographer;
}

//getters - 일반적으로 getter에 get을 붙이지 않는다는것은 위에서 언급한바 있다.
- (NSString*) caption;
- (NSString*) photographer;

//setters - setter에서 리턴값이 필요없다면 void로 지정한다.
- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;
@end


여기서 import한 Cocoa.h는 Cocoa 어플리케이션을 위한 기본 클래스들을 포함한다.
#import 명령은 하나의 파일을 여러번 읽어들이는 것을 자동적으로 방지해준다.

6.클래스 Implementation (.m) +-----+-----+-----+-----+-----+


위에서 정의한 Photo클래스의 .m 부분을 살펴보자.


#import "Photo.h"


@implementation Photo


- (NSString*) caption {
    return caption;
}
- (NSString*) photographer {
    return photographer;
}


@end


모든 메소드 내용들은 @implementation과 @end 사이에 기술된다.
이 getter 메소드들은 특별히 설명하지 않아도 친숙한 코딩방법이므로 넘어가도록 한다.


setter를 추가해보자.


- (void) setCaption: (NSString*)input
{
    [caption autorelease];
    caption = [input retain];
}


- (void) setPhotographer: (NSString*)input
{
    [photographer autorelease];
    photographer = [input retain];
}


settter는 좀 설명이 필요할 듯 하다.
하나의 setter안에는 두 변수가 사용된다. 하나는 기존의 오브젝트의 참조이고 하나는 파라매터로 넘어온 새로운 오브젝트이다.
만약 garbage collection을 사용할 수 있는 환경이라면 단순히 아래와 같이 적어주면 된다.


- (void) setCaption: (NSString*)input {
    caption = input;
}


하지만 그렇지 않다면 첫번째 예제와 같이 release와 retain을 수동적으로 적어줘야 할 것이다.
우선 release 방법에는 release 와 autorelease 의 두가지 방법이 있는데,
스탠다드 release는 오브젝트 참조를 바로 삭제하는 방법이고, autorelease는 가까운 시일내에 release할 것을 명령하는 방법이다.
단, autorelease를 지정한 경우에 기존 오브젝트는 현재 실행되고 있는 함수 안에서는 유효하다고 볼 수 있다.


setter메소드 안에서는 autorelease 를 사용할 것을 추천한다.
왜냐하면 새 오브젝트와 기존 오브젝트가 같은 오브젝트를 가르키고 있는 경우도 있기 때문이다.
이럴 경우 스탠다드 release를 사용해 버리면 원치 않게 새로 오브젝트를 삭제해 버리는 경우가 생긴다.


이 부분이 지금 바로 이해가 가지 않는다고 해도 좀 더 공부하면 서서히 알게 될 것이니 걱정하지 않아도 된다.

Init


인스턴스 변수들을 초기화하기 위해 Init 메소드를 정의한다.


- (id) init
{
    if ( self = [super init] )
    {
        [self setCaption:@"Default Caption"];
        [self setPhotographer:@"Default Photographer"];
    }
    return self;
}


여기서 if 문의 조건은 == 이 아니라 = 이다.
즉, 같다면 이라는 비교문이 아니라 [super init]의 결과를 self 에 대입하고 있다는 뜻이다.
이 예제 메소드에서는 슈퍼클래스에게 초기화를 대신 요청하고 그 결과에 문제가 없으면 다른 변수들에 기본값을 세팅하고 있다.

Dealloc


dealloc 메소드는 오브젝트가 메모리에서 삭제될때 불려진다.
고로 이 메소드 안에서 자신이 가지고 있는 인스턴스 변수들의 참조를 release 해 주면 된다.


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


클래스의 멤버 변수 였던 caption과 photographer는 그냥 스탠다드 release를 이용하여 release 한다.
이게 더 빠른 방법이므로 여기서 autorelase를 이용할 필요는 없다.


마지막 줄의 [super dealloc]은 슈퍼클래스에게 메모리 release를 요청하는 것인데,

만약 이것을 까먹는다면 memory leak 문제가 발생할 수 있을 것이다.


dealloc메소드는 garbage collection이 이용되고 있는 환경에서는 불려지지 않으며 대신 finalize 메소드를 정의한다.

7.메모리 관리법 좀더 살펴보기 +-----+-----+-----+-----+-----+


Objective-C에서는 참조카운터라는 메모리 관리 수법을 사용한다.


오브젝트를 생성(alloc) 하거나 보유(retain - 메소드 파라매터로 넘어올때) 할때 참조 카운터는 1씩 증가한다.
생성한 오브젝트를 retain 하면 카운터는 2가 되어있을 것이며 우리는 각각의 alloc 과 retain에 대해 release를 해줘야 한다.


하지만 실제로 우리가 오브젝트를 생성하는 경우는 아래 2가지 상황 뿐이다.


1.클래스의 인스턴스 변수로 사용할때
2.함수안에서 임시로 사용할 때


1번의 인스턴스 변수는 주로 autorelease와 dealloc에서 release 해주게 된다.


그럼 우리가 해결해야 할 것은 2번의 로컬변수들인데, 이것도 결국은 같은 이치로 alloc 이나 copy로 생성된 오브젝트를 사용후
함수안에서 autorelease나 release해주면 되는 것 뿐이다.


<1의 예제>
- (void) setTotalAmount: (NSNumber*)input
{
    [totalAmount autorelease];
    totalAmount = [input retain];
}


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


<2의 예제>
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];


// value2 는 alloc으로 생성하지 않았기 때문에 release 할 필요가 없다.
[value1 release];


이부분이 이해 된다면 Objective-C 의 메모리 관리의 90%를 파악했다고 할 수 있다.\

※ retain (오브젝트의 보유) 에 관하여

수신한 오브젝트를 파기하고 싶지 않은 경우도 있다. 예를 들어 인스턴스변수에 오브젝트를 캐쉬할 필요가 있을지도 모른다.
이런 경우, 오브젝트가 필요한지 어떤지 알수 있는건 본인 뿐임으로 사용중인 오브젝트를 파기당하지 않도록 보증하는 수단이 필요해진다. 이럴때 바로 retain 메소드를 사용한다. 이 메소드는 보류중인 autorelease 효과를 정지시켜 그 오브젝트가 필요없어 질때까지 relase되지 않도록 보장해준다.

8.로깅 +-----+-----+-----+-----+-----+


Objective-C의 로깅은 매우 심플하다. NSLog 함수가 거의 printf() 와 유사하기 때문이다.
단, %@ 라는 오브젝트를 표현하는 포멧이 추가되어 있다.


NSLog ( @"The current date and time is: %@", [NSDate date] );


NSLog를 이용하여 오브젝트를 콘솔에 찍으면 사실 오브젝트의 description메소드가 불려짐으로,
이를 오버라이드하여 원하는 결과를 찍어볼 수 있다.

9.프로퍼티 +-----+-----+-----+-----+-----+


Objective-C의 특징에 설명되어 있음으로 예제만 나열하도록 한다.


위에서 봐 온 getter와 setter가 적혀있는 예제를 property를 이용하여 아래와 같이 간략해진다.


#import

@interface Photo : NSObject {
    NSString* caption;
    NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end



#import "Photo.h"

@implementation Photo

@synthesize caption;
@synthesize photographer;

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

@end


@synthesize는 소스내에 정의되어 있지 않은 getter/setter만 자동생성 해주기 때문에 안심하고 사용할 수 있다.

10.Nil 오브젝트의 메소드 호출 +-----+-----+-----+-----+-----+


Objective-C의 nil 오브젝트는 다른 프로그래밍 언어에서 말하는 NULL 오브젝트와 동일한 개념이다.
한가지 다른점은 nil인 오브젝트의 메소드를 호출하여도 에러가 나지 않는다는 점이다.


이것은 여러가지 방법으로 활용되지만 가장 편리한 점은 널 체크를 하지 않고 메소드를 호출할 수 있다는 점이다.


또한 dealloc의 성능을 높이기 위해서 사용할 수도 있다.
- (void) dealloc
{
    self.caption = nil;
    self.photographer = nil;
    [super dealloc];
}


여기서 nil을 인스턴스 변수의 값으로 넘기면 setter는 nil을 retain하고 기존 오브젝트를 release 한다.
이 방법은 dealloc에서 매우 효율적인데, 왜냐하면 nil을 세팅하므로써 변수가 다른 오브젝트를 참조할 가능성이 없어지기 때문이다.


self.를 붙여 setter를 호출해야하지 caption = nil; 이라고 하면 잘못된 방법이므로 memory leak를 초래한다.

11.카테고리 +-----+-----+-----+-----+-----+

카테고리는 Objective-C의 유용한 특징중에 하나이다.
요점부터 말하자면 카테고리는 기존의 클래스의 서브클래스를 생성하지 않고도 메소드를 추가할 수 있다.
(확장하고자 하는 클래스의 내부구조를 파악할 필요가 없다.)


이는 매우 유용한데, 왜냐하면 예를 들어 NSString에 그냥 카테고리를 추가만 하면 그 프로젝트 안에서 카테고리로서 추가된 메소드를 사용 할 수 있기 때문이다. 즉, NSString을 계승하여 새 클래스를 만들어 그것을 alloc하여 쓴다.. 하는 복잡한 과정이 필요없다는 뜻이자.


예제를 살펴보자.

<헤더>
#import

@interface NSString (Utilities)
- (BOOL) isURL;
@end

<클래스>
#import "NSString-Utilities.h"

@implementation NSString (Utilities)

- (BOOL) isURL
{
    if ( [self hasPrefix:@"http://"] )
        return YES;
    else
        return NO;
}

@end


일반 클래스와의 차이는 단지 슈퍼클래스의 정의가 없고 클래스 명 뒤의 괄호안에 카테고리 명을 써 준 다는 점 뿐이다.


위에서 추가한 메소드를 사용해 보는 예제를 살펴보자
NSString* string1 = @"http://pixar.com/
";
NSString* string2 = @"Pixar";

if ( [string1 isURL] )
    NSLog (@"string1 is a URL");

if ( [string2 isURL] )
    NSLog (@"string2 is a URL");  


카테고리는 서브클래스 확장과는 달리 인스턴스 변수는 추가 할 수 없다.
하지만 기존의 메소드를 오버라이드 하는것은 가능한데 이는 매우 신중히 해야할 작업중 하나이다.


기억해둬야 할 중요한 사항은, 클래스 카테고리를 사용한 변경은 어플리케이션의 모든 클래스 인스턴스에 영향을 준다는 사실이다.



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10075417177
Posted by 오늘마감

댓글을 달아 주세요

아이폰기본사용2010. 6. 29. 10:50
PC Suite 기본 사용법

프로그램 명칭 : PC Suite (手机助手)

프로그램 성격

  • 기본적으로 아이튠스와 앱스토어를 합친 기능에 WinSCP 등의 파일 관리 기능까지 추가
  • 최신 버전에서는 Cydia 어플을 컴에서 설치하거나 소스 추가 등의 기능도 추가됨
  • 다양한 포맷의 어플을 직접 설치할 수 있음
  • 파일관리, 미디어 제작/컨버팅/관리, 통화목록, 연락처, SMS 등 다양한 부가기능
  • 아직까지 iPod과 연동 기능은 제공하지 않음
  • 빠른 업데이트 속도로 크랙어플을 소개하나 아쉽게도 중국어로만 제공 (파일명만 알면 설치는 가능)
  • 최근 영문 웹사이트를 통한 어플 설치도 서비스하고 있음

프로그램 다운로드 :


* BlackRa1n으로 탈옥 후 프로그램을 실행시키면 아래 그림처럼  "Jailbreak가 되지 않았다"는 메시지가 뜨는 데
   이 경우 여기를 참조하여 해결하세요.





기본 화면
 :

좌상단의 아이폰 모양 아이콘 메뉴를 클릭하면 아래 그림처럼 해당 언어를 선택할 수 있습니다.

아이폰과 연결
 : 프로그램 중간의 연결하기 혹은 우상단 부분을 클릭해서 USB 유선 연결 혹은 Wi-Fi를 통한 무선 연결 선택
                        (무선 연결 시 여기 를 참조)


기본 메뉴 설명

1. 상단메뉴

1.1. 시작(Start) : 아이폰 관련 최신 뉴스, 프로그램 정보 등


1.2. 관리(Management)
: 사진, 아이팟, 연락처, 문자내역, 캘린더, 메모, 전자책, 통화내역, 알람 등


아래 그림은 iPod 메뉴인데 아쉽게도 아직까지는 아이폰과 연동 기능을 제공하지 않고 있음
다만 중국의 구글인 Baidu라는 검색 사이트와 연동하여 음악을 바로 검색하고 무료로 다운 받을 수 있는 기능을 제공


1.3. 시스템(System) : 아이폰 문제 해결, 발송자 지역정보 조회, 파일 관리, 프로그램 관리, 백업/복원 등


1.4. 미디어(Media)
: 배경화면, 테마, 벨소리, 스샷, 벨소리 제작, 음악/동영상 컨버팅, RSS 피드 관리 등


1.5. 커뮤니티(Community)
: 제작사 소개, 아이폰 관련 블로그 등 링크


1.6. 갱신(Updates)
: 제작사 프로그램 업데이트 정보



2. 좌측메뉴
 : 상단 메뉴 중 제일 중요한 기능 등만 모아 놓은 곳

2.1. 파일(Files) : 아이폰에 직접 접속하여 파일 관리 및 테마 파일 등 설치 (WinSCP 등 대체, 계정/비번 필요 없음)


2.2. 어플(Apps) : 각종 어둠의 경로 어플 다운로드/설치/삭제, Cydia 어플 유선 설치, 소스 추가
                   (어플 설치는 여기 참조, Cydia 혹은 어플 수동 설치는 여기 참조)



2.3. 사진(Pictures): 아이폰 내  사진 및 스샷 관리


2.4. 문서(Docs)
: 아이폰에 직접 접속하여 My Documents 폴더를 관리


2.5. 채팅(Chat) : 컴에서 바로 문자 발송/수신 기능 제공 및 문자 내역 관리



2.6. 전원(Turn Off): 아이폰 리스프링/재부팅/전원끄기



세부 강좌 링크

PC Suite 한글화 파일

어플 설치 방법

Cydia 어플 유선 설치/소스 추가 및 다양한 포맷의 어플 직접 설치 방법

설치한 어플 보관 장소

벨소리 제작 및 적용 방법

아이폰용 동영상 제작 방법 (포맷 변환)

테마 적용 방법

배경 파일 제작 및 적용 방법

내 컴에서 아이폰에 무선 접속 방법

스샷 찍기

사진 관리 방법

컴에서 채팅하듯 문자 주고 받기

기존에 사용하던 스마트폰의 연락처 등 중요 데이터를  전송하는 방법
 


출처 : http://blog.naver.com/PostView.nhn?blogId=jkw1120&logNo=60097420517
Posted by 오늘마감

댓글을 달아 주세요

오브젝트C2010. 6. 22. 17:53
Objective-C의 기본 문법

아무리 무작정 따라하기 라지만, 역시 기본 문법도 모르고는 앞으로 나아가기가 쉽지 않다.

그렇다고 또 한권짜리 문법책을 읽기엔 너무 지루해서 흐름이 멈춘다.

다행히 기본 문법을 한페이지(?)로 간략히 메모해놓은 사이트가 있다.

앞에서 정리한 Objective-C의 특징과 겹치는 부분들도 있지만 훨씬 이해하기 편하게 적혀있다.


원글Learn Objective-C by Scott Stevenson
작성자 블로그의 첫페이지에 있는 말.


All of the buildings, all of those cars were once just a dream in somebody's head. — Peter Gabriel
(모든 빌딩과 모든 자동차들도 원래는 누군가의 머리속의 꿈에 지나지 않았다.)


<순서>
 1.메소드의 호출
 2.접근자
 3.오브젝트의 생성
 4.기본 메모리 관리법
 5.클래스 Interface (.h)
 6.클래스 Implementation (.m)
 7.메모리 관리법 좀더 살펴보기
 8.로깅
 9.프로퍼티
10.Nil 오브젝트의 메소드 호출
11.카테고리


1.메소드의 호출 +-----+-----+-----+-----+-----+


기본 문법
[object method];
[object methodWithInput:input];


다른 언어에서 말하는 오브젝트명.메소드명 이 여기서는 [오브젝트 메소드] 괄호에 둘러쌓여있고 스페이스로 구분하는 형식이 된다.

파라메터를 가지는 경우에는 [오브젝트 메소드:파라매터] 로 불린다. (메소드와 파라매터사이에 콜론이 존재)

리턴값이 있는 경우
output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];


클래스 메소드도 같은 문법으로 호출 가능하다.
id myObject = [NSString string];


여기서 id란 myObject가 어떤 오브젝트의 참조도 될 수 있다는 뜻이며,
즉 컴파일 할 때에도 클래스 타입을 알지 못한다는 뜻이다.


하지만 여기선 딱 보면 NSString이란걸 알 수 있기에 아래와 같이도 쓸수 있다.
NSString* myString = [NSString string];


오브젝트 타입 옆에 *(아스타리스크)가 있는걸 볼 수 있다.
모든 Objective-c의 오브젝트 변수들은 포인터 타입이다.
id 타입은 이미 포인터 타입으로 정의 되어 있기 때문에 *(아스타리스크)를 붙일 필요가 없는것 뿐이다.


Nasted 메세지


일반적인 많은 프로그래밍 언어에서 Nasted 메소드나 함수를 호출할 때 아래와 같은 문법을 사용한다.
function1 ( function2() );


이것이 Objective-C에선 아래와 같이 표현된다.
[NSString stringWithFormat:[prefs format]];


다중 파라매터를 가지는 메소드 호출


이런 경우, Objective-C에서는 메소드 명을 여러 조각으로 나누어 사용한다.
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;


위의 메소드를 호출하는 방법은 아래와 같다.
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];


결국 이 말은 파라매터명이란 것이 존재 하지 않는 다는 뜻이며,
런타임 시스템에서 메소드 명은 writeToFile:atomically: 로 인식된다.

2.접근자 +-----+-----+-----+-----+-----+


Objective-c의 모든 인스턴스 변수들은 private이다. 즉 접근자를 사용하여 억세스 하여야 한다는 소리이다.


일반적인 문법


[photo setCaption:@"Day at the Beach"];
output = [photo caption];


두번째 줄의 코드는 인스턴스 변수를 직접 읽는다는 뜻이 아니라 caption이라는 메소드를 부르고 있는 것이다.
Objective-C에서는 일반적으로 getter 메소드에 get을 붙이지 않고 사용한다.


.(dot)를 이용한 문법


.(dot)는 접근자(getter and setter)를 위해 Objective-C 2.0에 새로 추가된 문법이다.


photo.caption = @"Day at the Beach";
output = photo.caption;


동일한 프로젝트 내에서는 한쪽 문법만 사용하는 것이 통일성 있게 코딩하는 방법이다.
또한 .(dot)는 일반 메소드 호출에는 사용할 수 없음을 명심하자.

3.오브젝트의 생성 +-----+-----+-----+-----+-----+


오브젝트를 생성하는 방법은 여러가지가 있다.


자동할당


NSString* myString = [NSString string];


자동으로 생성하여 할당해주는 편리한 방법이다. 자세한 내용은 나중에 살펴보도록 한다.
하지만 대부분의 오브젝트는 아래에 설명하는 수동 할당 방법을 사용하여야 한다.


수동할당


NSString* myString = [[NSString alloc] init];


이것은 메소드의 Nested된 호출방식이다.
우선 NSString클래스의 alloc메소드를 부른다.
이는 매우 하위레벨의 호출로써 메모리를 확보하고 오브젝트를 인스턴스화 한다.


다음으로 생성된 오브젝트의 init 메소드를 부른다.
init은 주로 초기화 작업을 하는데 예를 들면 내부 변수들의 인스턴스를 생성하는 작업 등이다.


값을 가지는 다른 버젼의 init을 호출하는 경우도 있다.


NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];

4.기본 메모리 관리법 +-----+-----+-----+-----+-----+


만약 Mac OS X에서 돌아가는 어플리케이션을 개발한다면 garbage collection을 사용할 수 있다.
다시 말하자면 복잡한 경우를 제외하고는 메모리 관리를 하지 않아도 된다는 뜻이다.


하지만 우리는 항상 garbage collection을 제공하는 환경하에서 작업하는 것이 아니기 때문에
기본 메모리 관리법을 알아 두도록 하자.


alloc을 이용하여 수동적으로 오브젝트를 생성하였을 경우에는 이를 release 하는 작업을 해야 한다.
반대로 자동으로 할당해주는 방법으로 생성한 오브젝트는 수동으로 release 하면 안된다.
이는 프로그램에 문제를 발생시킨다.


// string1 는 자동으로 release 될 것이다.
NSString* string1 = [NSString string];


// string2 는 사용이 끝난후 수동으로 release 해주어야 한다.
NSString* string2 = [[NSString alloc] init];
[string2 release];


여기서 string1 는 함수의 끝에서 자동으로 release된다고 생각하면 된다.


메모리 관리에 대해서 좀 더 알아둘 내용이 있지만
몇가지 다른 개념을 먼저 알고 가는 것이 좋음으로 뒤쪽에서 다시 보도록 한다.

5.클래스 Interface (.h) +-----+-----+-----+-----+-----+


Objective-C에서 클래스를 만드는 방법은 매우 간단하다.
.h 파일에 인터페이스를 적고 .m 파일에 내용을 적으면 된다.


.h 파일
인스턴스 변수와 퍼블릭 메소드의 인터페이스를 정의한다.


.m 파일
.h 에 정의한 인터페이스들을 implement한다.
그리고 private 메소드 들도 여기에 적어준다.


<.h 파일의 예>
#import <Cocoa/Cocoa.h>

@interface Photo : NSObject {
    NSString* caption;
    NSString* photographer;
}

//getters - 일반적으로 getter에 get을 붙이지 않는다는것은 위에서 언급한바 있다.
- (NSString*) caption;
- (NSString*) photographer;

//setters - setter에서 리턴값이 필요없다면 void로 지정한다.
- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;
@end


여기서 import한 Cocoa.h는 Cocoa 어플리케이션을 위한 기본 클래스들을 포함한다.
#import 명령은 하나의 파일을 여러번 읽어들이는 것을 자동적으로 방지해준다.

6.클래스 Implementation (.m) +-----+-----+-----+-----+-----+


위에서 정의한 Photo클래스의 .m 부분을 살펴보자.


#import "Photo.h"


@implementation Photo


- (NSString*) caption {
    return caption;
}
- (NSString*) photographer {
    return photographer;
}


@end


모든 메소드 내용들은 @implementation과 @end 사이에 기술된다.
이 getter 메소드들은 특별히 설명하지 않아도 친숙한 코딩방법이므로 넘어가도록 한다.


setter를 추가해보자.


- (void) setCaption: (NSString*)input
{
    [caption autorelease];
    caption = [input retain];
}


- (void) setPhotographer: (NSString*)input
{
    [photographer autorelease];
    photographer = [input retain];
}


settter는 좀 설명이 필요할 듯 하다.
하나의 setter안에는 두 변수가 사용된다. 하나는 기존의 오브젝트의 참조이고 하나는 파라매터로 넘어온 새로운 오브젝트이다.
만약 garbage collection을 사용할 수 있는 환경이라면 단순히 아래와 같이 적어주면 된다.


- (void) setCaption: (NSString*)input {
    caption = input;
}


하지만 그렇지 않다면 첫번째 예제와 같이 release와 retain을 수동적으로 적어줘야 할 것이다.
우선 release 방법에는 release 와 autorelease 의 두가지 방법이 있는데,
스탠다드 release는 오브젝트 참조를 바로 삭제하는 방법이고, autorelease는 가까운 시일내에 release할 것을 명령하는 방법이다.
단, autorelease를 지정한 경우에 기존 오브젝트는 현재 실행되고 있는 함수 안에서는 유효하다고 볼 수 있다.


setter메소드 안에서는 autorelease 를 사용할 것을 추천한다.
왜냐하면 새 오브젝트와 기존 오브젝트가 같은 오브젝트를 가르키고 있는 경우도 있기 때문이다.
이럴 경우 스탠다드 release를 사용해 버리면 원치 않게 새로 오브젝트를 삭제해 버리는 경우가 생긴다.


이 부분이 지금 바로 이해가 가지 않는다고 해도 좀 더 공부하면 서서히 알게 될 것이니 걱정하지 않아도 된다.

Init


인스턴스 변수들을 초기화하기 위해 Init 메소드를 정의한다.


- (id) init
{
    if ( self = [super init] )
    {
        [self setCaption:@"Default Caption"];
        [self setPhotographer:@"Default Photographer"];
    }
    return self;
}


여기서 if 문의 조건은 == 이 아니라 = 이다.
즉, 같다면 이라는 비교문이 아니라 [super init]의 결과를 self 에 대입하고 있다는 뜻이다.
이 예제 메소드에서는 슈퍼클래스에게 초기화를 대신 요청하고 그 결과에 문제가 없으면 다른 변수들에 기본값을 세팅하고 있다.

Dealloc


dealloc 메소드는 오브젝트가 메모리에서 삭제될때 불려진다.
고로 이 메소드 안에서 자신이 가지고 있는 인스턴스 변수들의 참조를 release 해 주면 된다.


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


클래스의 멤버 변수 였던 caption과 photographer는 그냥 스탠다드 release를 이용하여 release 한다.
이게 더 빠른 방법이므로 여기서 autorelase를 이용할 필요는 없다.


마지막 줄의 [super dealloc]은 슈퍼클래스에게 메모리 release를 요청하는 것인데,

만약 이것을 까먹는다면 memory leak 문제가 발생할 수 있을 것이다.


dealloc메소드는 garbage collection이 이용되고 있는 환경에서는 불려지지 않으며 대신 finalize 메소드를 정의한다.

7.메모리 관리법 좀더 살펴보기 +-----+-----+-----+-----+-----+


Objective-C에서는 참조카운터라는 메모리 관리 수법을 사용한다.


오브젝트를 생성(alloc) 하거나 보유(retain - 메소드 파라매터로 넘어올때) 할때 참조 카운터는 1씩 증가한다.
생성한 오브젝트를 retain 하면 카운터는 2가 되어있을 것이며 우리는 각각의 alloc 과 retain에 대해 release를 해줘야 한다.


하지만 실제로 우리가 오브젝트를 생성하는 경우는 아래 2가지 상황 뿐이다.


1.클래스의 인스턴스 변수로 사용할때
2.함수안에서 임시로 사용할 때


1번의 인스턴스 변수는 주로 autorelease와 dealloc에서 release 해주게 된다.


그럼 우리가 해결해야 할 것은 2번의 로컬변수들인데, 이것도 결국은 같은 이치로 alloc 이나 copy로 생성된 오브젝트를 사용후
함수안에서 autorelease나 release해주면 되는 것 뿐이다.


<1의 예제>
- (void) setTotalAmount: (NSNumber*)input
{
    [totalAmount autorelease];
    totalAmount = [input retain];
}


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


<2의 예제>
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];


// value2 는 alloc으로 생성하지 않았기 때문에 release 할 필요가 없다.
[value1 release];


이부분이 이해 된다면 Objective-C 의 메모리 관리의 90%를 파악했다고 할 수 있다.\

※ retain (오브젝트의 보유) 에 관하여

수신한 오브젝트를 파기하고 싶지 않은 경우도 있다. 예를 들어 인스턴스변수에 오브젝트를 캐쉬할 필요가 있을지도 모른다.
이런 경우, 오브젝트가 필요한지 어떤지 알수 있는건 본인 뿐임으로 사용중인 오브젝트를 파기당하지 않도록 보증하는 수단이 필요해진다. 이럴때 바로 retain 메소드를 사용한다. 이 메소드는 보류중인 autorelease 효과를 정지시켜 그 오브젝트가 필요없어 질때까지 relase되지 않도록 보장해준다.

8.로깅 +-----+-----+-----+-----+-----+


Objective-C의 로깅은 매우 심플하다. NSLog 함수가 거의 printf() 와 유사하기 때문이다.
단, %@ 라는 오브젝트를 표현하는 포멧이 추가되어 있다.


NSLog ( @"The current date and time is: %@", [NSDate date] );


NSLog를 이용하여 오브젝트를 콘솔에 찍으면 사실 오브젝트의 description메소드가 불려짐으로,
이를 오버라이드하여 원하는 결과를 찍어볼 수 있다.

9.프로퍼티 +-----+-----+-----+-----+-----+


Objective-C의 특징에 설명되어 있음으로 예제만 나열하도록 한다.


위에서 봐 온 getter와 setter가 적혀있는 예제를 property를 이용하여 아래와 같이 간략해진다.

<Photo.h>
#import <Cocoa/Cocoa.h>

@interface Photo : NSObject {
    NSString* caption;
    NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@end


<Photo.m>
#import "Photo.h"

@implementation Photo

@synthesize caption;
@synthesize photographer;

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

@end


@synthesize는 소스내에 정의되어 있지 않은 getter/setter만 자동생성 해주기 때문에 안심하고 사용할 수 있다.

10.Nil 오브젝트의 메소드 호출 +-----+-----+-----+-----+-----+


Objective-C의 nil 오브젝트는 다른 프로그래밍 언어에서 말하는 NULL 오브젝트와 동일한 개념이다.
한가지 다른점은 nil인 오브젝트의 메소드를 호출하여도 에러가 나지 않는다는 점이다.


이것은 여러가지 방법으로 활용되지만 가장 편리한 점은 널 체크를 하지 않고 메소드를 호출할 수 있다는 점이다.


또한 dealloc의 성능을 높이기 위해서 사용할 수도 있다.
- (void) dealloc
{
    self.caption = nil;
    self.photographer = nil;
    [super dealloc];
}


여기서 nil을 인스턴스 변수의 값으로 넘기면 setter는 nil을 retain하고 기존 오브젝트를 release 한다.
이 방법은 dealloc에서 매우 효율적인데, 왜냐하면 nil을 세팅하므로써 변수가 다른 오브젝트를 참조할 가능성이 없어지기 때문이다.


self.를 붙여 setter를 호출해야하지 caption = nil; 이라고 하면 잘못된 방법이므로 memory leak를 초래한다.

11.카테고리 +-----+-----+-----+-----+-----+

카테고리는 Objective-C의 유용한 특징중에 하나이다.
요점부터 말하자면 카테고리는 기존의 클래스의 서브클래스를 생성하지 않고도 메소드를 추가할 수 있다.
(확장하고자 하는 클래스의 내부구조를 파악할 필요가 없다.)


이는 매우 유용한데, 왜냐하면 예를 들어 NSString에 그냥 카테고리를 추가만 하면 그 프로젝트 안에서 카테고리로서 추가된 메소드를 사용 할 수 있기 때문이다. 즉, NSString을 계승하여 새 클래스를 만들어 그것을 alloc하여 쓴다.. 하는 복잡한 과정이 필요없다는 뜻이자.


예제를 살펴보자.

<헤더>
#import <Cocoa/Cocoa.h>

@interface NSString (Utilities)
- (BOOL) isURL;
@end

<클래스>
#import "NSString-Utilities.h"

@implementation NSString (Utilities)

- (BOOL) isURL
{
    if ( [self hasPrefix:@"http://"] )
        return YES;
    else
        return NO;
}

@end


일반 클래스와의 차이는 단지 슈퍼클래스의 정의가 없고 클래스 명 뒤의 괄호안에 카테고리 명을 써 준 다는 점 뿐이다.


위에서 추가한 메소드를 사용해 보는 예제를 살펴보자
";
NSString* string2 = @"Pixar";

if ( [string1 isURL] )
    NSLog (@"string1 is a URL");

if ( [string2 isURL] )
    NSLog (@"string2 is a URL");  


카테고리는 서브클래스 확장과는 달리 인스턴스 변수는 추가 할 수 없다.
하지만 기존의 메소드를 오버라이드 하는것은 가능한데 이는 매우 신중히 해야할 작업중 하나이다.


기억해둬야 할 중요한 사항은, 클래스 카테고리를 사용한 변경은 어플리케이션의 모든 클래스 인스턴스에 영향을 준다는 사실이다.



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10075417177

'오브젝트C' 카테고리의 다른 글

The Objective-C 2.0 Programming Language  (0) 2010.06.24
Objective-C  (0) 2010.06.22
Objective-C의 기본 문법  (0) 2010.06.22
Objective-C의 특징  (0) 2010.06.22
[Objective-C]Interface Builder 기본 사용  (0) 2010.06.22
[Objective-C]번들  (0) 2010.06.22
Posted by 오늘마감

댓글을 달아 주세요

오브젝트C2010. 6. 22. 09:54
[Objective-C]Interface Builder 기본 사용

Interface Builder를 사용하여 간단한 HelloWorld프로그램을 제작해 보았다. 이제부터는 Iphone 시뮬레이터를 사용한다.

새로운 프로젝트 생성 창이다. 여기서 iPhone OS를 선택해주고, Application을 선택해주면 상단과 같은 목록이 뜨는데 Window-based Application을 선택해 준다. 종류별 간단한 설명을 하자면 다음과 같다.

* Navigation-Based : 내비게이션 컨트롤러를 사용하는 응용프로그램으로 대표적인 예는 주소록이다.

* OpenGL ES : 게임과 같은 OpenGL 그래픽 기반의 응용프로그램

* Tab Bar : 탭 바를 사용하는 응용프로그램. 아이팟 프로그램이 대표적

* Utility : 앞뒤면이 있는 응용프로그램. 예로 주식 프로그램

* View-Based : 뷰 기반 프로그램. 뷰에 그림을 그리고 윈도우에 뷰를 표시한다.

* Window-Based : 메인 아이폰 윈도우만 가지고 시작하는 프로그램. 이 메인 윈도우에서 어느 프로그램이든 시작할 수 있다.

Window-based Application을 선택해주고 프로그램 이름을 정해주면 다음과 같이 기본 세팅이 된다. 여기서 프로그램 이름을 example_1로 해 주었기 때문에 다음과 같이 설정되어 기본 세팅 된 화면이다.

example_1AppDelegate.h 의 코드에 내용을 추가한 모습이다. 추가 내용으로는 UILabel *label 을 추가하고 property에도 label을 추가한 모습이다.

이 Delegate 클래스는 버튼을 누르거나 슬라이더를 움직이는 식의 아이폰 윈도우에서 일어나는 액션에 응답하는 메소드 들이 작성된다. 인터페이스 빌더와 대응하여 각각의 컨트롤들에 대응하는 메소드들이 작성된다. 또한 아이폰 윈도우에 있는 컨트롤들의 값에 대응하는 변수도 포함하게 되는데 이를 아웃렛(Outlet)이라고 한다.

여기서 btnClick은 버튼 컨트롤이 클릭되었을때 대응하는 메소드가 된다. UILabel의 경우 버튼이 클릭 되었을 때 화면에 정보를 뿌려주기 위한 객체이다.

example_1AppDelegate.m의 실제 구현 모습이다. @property로 설정된 내용을 @synthesize해주어 접근자를 생성해 준다.

또한 btnClick의 실제 구현을 해주는데 단순히 label에 텍스트를 넣어주는 것이다. 이외의 것은 건들지 않았다.

이제 인터페이스를 구성할 차례이다. 좌측 탭에서 Resources로 가보면 .plist와 .xib파일이 보일텐데 xib파일은 인터페이스 빌더 파일이다. 더블클릭을 하게 되면 인터페이스 빌더가 실행된다.

보는바와 같이 인터페이스 빌더가 실행된 모습이다.

상당히 생소한 모습으로 실제 인터페이스 빌더는 처음 써보았다.

좌측 창의 모습인데 라이브러리에 보게되면 각종 사용하게 될 컨트롤러들이 보이고 있다.

좌측창에서 Label을 선택하여 드래그한 후 중앙의 실제 iPhone화면 구성 창에 드래그 해준다.

이렇게 드래그 앤 드랍방식으로 화면을 구성할 컨트롤들을 배치할 수 있다.

화면과 같이 Label자체의 크기역시 조절 할 수 있다. 적절한 크기로 만들어 배치해 준다.

이제 좌측 창에서 Round Rect Button을 선택해 준다.

역시 드래그 하여 적절한 위치에다 놓아주면 배치는 종료된다.

버튼을 더블클릭하면 내용을 바꿀 수 있는데 더블클릭하여 버튼에 표시될 내용을 적어준다. Label역시 가능하며 버튼 또한 Label처럼 사이즈 조절이 가능하다.

이제부터 중요한 작업으로 3번째 창을보면 프로젝트명 Delegate가 보일것이다. 여기서는 example1로 프로젝트명을 했기 때문에 Example1 App Delegate가 보일것이다. 버튼의 액션을 할당해 주기 위해서 버튼에 control버튼을 누르고 드래그하여 Delegate로 끌고가면 파란색 선이 나오게 된다.

버튼을 띠게 되면 아까 선언해 줬던 btnClick이란 메소드가 보일 것이다. 이는 Delegate 클래스에 메소드 1개만 선언해 주었기 때문에 이렇게 나오는데 여러개를 선언해 주었다면 해당 목록에서 원하는 메소드를 찾아 선택하면 된다. 이로서 버튼이 클릭되면 수행할 메소드 할당이 끝났다.

이제 반대로 변수로 선언해 준 label객체가 무엇인지 할당해 주어야 한다. 3번째 창에서 Delegate를 control 드래그 하면 역시 파란선이 나오며 드래그 되는데 아까 배치해 두었던 label에 놓아준다.

아까와 마찬가지고 선언해 두었던 컨트롤들의 목록이 뜨게 되는데 1개만 선언해 주었기 때문에 label을 선택해 준다.

최종적으로 ui의 모습이다.

이제 interface builder를 저장하고 xcode에서 실행시키면 된다. 본인은 interface builder를 저장하지 않아서 정상작동하지 않아 고민을 많이 했다...

아이폰 시뮬레이터의 모습이다. 이제 버튼을 눌러보자

Hello World!라고 지정해 두었던 문자가 Label에 찍히는 것을 볼 수 있다.



출처 : http://blog.naver.com/PostView.nhn?blogId=khagaa&logNo=30085139048

'오브젝트C' 카테고리의 다른 글

Objective-C의 기본 문법  (0) 2010.06.22
Objective-C의 특징  (0) 2010.06.22
[Objective-C]Interface Builder 기본 사용  (0) 2010.06.22
[Objective-C]번들  (0) 2010.06.22
[Objective-C]메세지 포워딩  (0) 2010.06.22
[Objective-C]존  (0) 2010.06.22
Posted by 오늘마감

댓글을 달아 주세요

오브젝트C2010. 6. 22. 09:53
[Objective-C] 기본 클래스
@interface 로 클래스 선언 및 메소드, 변수 선언.
@implementation 으로 선언된 것들 구현.

@interface 나 @implementation 끝에는 @end 로 끝맺음을 해 주어야 하고 @end 다음에 ;를 넣지 않는다.
@end를 넣지 않아도 에러는 나지 않지만 경고는 뜨게 된다.

1개의 m 파일에 다수의 @interface 와 @implementation을 넣을수 있지만 @interface 와 @implementation 은 꼭 짝을 이루어야 한다.
선언부 없는 구현이나 구현부 없는 선언 혹은 1개의 선언으로 다수의 구현은 에러를 발생 시킨다.
.h로 헤더를 분리할 경우 구현부 파일은 .m으로 저장하며 선언부 파일과 구현부 파일은 파일명이 일치 해야 한다.
기본적으로 헤더만 #import 하기 때문에 컴파일러는 구현부가 어떤것인지를 모르게 된다. 파일명으로 구분하는 듯 한데 다른이름으로 할 경우 (선언부나 구현부 파일명 불일치) 에러가 발생하게 된다.

테스트 해본 결과로 파일명과 클래스명이 일치할 필요는 없다. (자바나 액션의 경우 일치해야 함) 다만 경고가 뜬다. 하지만 어찌됐건 프로그램은 작동하더라.

접근 제한자가 있기는 한다고 하는데 아직까지 사용한적은 없음. 기본적으로 protected 로 선언된다고 함.
접근제한자는 @private, @protected, @public 으로 구분.

다수의 main 메소드가 있다면 에러 발생. .m파일에서 main 메소드를 찾아서 그 시점부터 시작하는듯 함.

그 외의 개념들은 java 나 actionscript 의 클래스들과 동일한 것 같습니다.
상속에 대한 개념또한 상속 받은 서브 클래스들은 슈퍼클래스의 protected, public 메소드를 그대로 사용할 수 있고 오버라이딩도 할 수 있으며 변수 추가도 할수 있습니다. 변수에 대한 오버라이드 역시 지원하지 않습니다.

메소드 역시 문자나 숫자 이외에도 객체형태의 파라미터를 넘겨 줄 수 있습니다.


출처 : http://blog.naver.com/PostView.nhn?blogId=khagaa&logNo=30083054527
Posted by 오늘마감

댓글을 달아 주세요