XCODE2011. 4. 9. 11:14

프로젝트를 생성하고 좌측창을 보게되면 다음과 같이 표시가 된다. 내용을 살펴보면 다음과 같다.

 

* Classes

작성한 대부분의 코드는 여기에 들어가게 된다. Objective-C의 원래 있어야 할 곳이다. 코드 정리를 위해 Classes 폴더 하위로 폴더를 추가 생성해도 된다.

 

* Other Sources

Objective-C 클래스가 아닌 소스 코드의 위치이다. 새 아이폰 어플리케이션이 제작되면 2개의 파일이 생성된다.

프로젝트명.pch -> 미리 컴파일한 헤더(precomplied header'를 의미하며 프로젝트에서 사용하는 외부 프레임워크의 헤더파일 목록이다.

Xcode에서 이 파일이 담고 있는 헤더들을 미리 컴파일하는데 이렇게 되면 build를 했을경우 컴파일 하는 시간이 줄어든다. 가장 일반적으로 사용하는 헤더 파일들은 이미 포함되어 있기 때문에 신경쓰지 않아도 된다.

main.m -> main() 메소드가 있는곳으로 보통은 수정하지 않는다.(아이폰 어플리케이션에서)

 

* Resources

애플리케이션의 일부로, 코드가 아닌 파일들을 담고 있다.아이콘, 이미지, 소리, 동영상, 텍스트, 기타 프로그램 수행상의 프로퍼티 리스트 등이 포함된다. 어플리케이션은 각각의 샌드박스에서 실행되므로 필요한 모든 파일을 여기에 넣어야 한다. 이는 허가된API 이외에는 다른곳의 파일에 접근할수 없기 때문이다. 이 폴더에는 기본적으로 3가지 항목이 포함되어 있다.

프로젝트명Controller.xib -> 인터페이스 빌더에 대한 내용을 저장하고 있다.

프로젝트명-Info.plist -> 애플리케이션 정보를 담는 프로퍼티 리스트이다.

MainWindow.xib -> 애플리케이션의 기본 인터페이스 빌더파일이다. 애플리케이션이 간단한경우 보통 손을댈 필요가 없다.

 

* Framework

코드는 물론 이미지나 소리팡일들과 같은 자원들이 담긴 특별한 종류의 라이브러리이다. 이 폴더에 추가된 프레임 워크나 라이브러리는 애플리케이셔넹 링크되고, 코드에서 그 프레임워크나 라이브러리의 객체, 함수, 자원을 사용할 수 있다. 기본적으로 사용되는 프레임워크들과 라이브러리들은 기본적으로 링크되므로 추가작업은 필요없다. 하지만 추가적인 라이브러리나 프레임워크는 추가 시켜야 한다.

 

* Products

프로젝트가 생성한 애플리케이션을 담는다. 프로젝트명.app이라는 항목을 볼 수 있는데 이는 프로젝트가 생성한 결과물이다.



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

'XCODE' 카테고리의 다른 글

xcode에서 iphone app 이름 변경  (0) 2011.04.09
Xcode 삭제  (0) 2011.04.09
[Objective-C] Xcode프로젝트 창  (0) 2011.04.09
[펌] Xcode 에 Subversion 적용하기  (0) 2011.04.09
XCODE용 디버그 메크로  (0) 2011.04.09
새로운 개발툴 XCODE 4  (0) 2011.04.09
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:55
[Objective-C] AutoSize 속성
아이폰에서 AutoSize속성을 사용하면 중력센서를 사용하여 기기 회전에 따른 처리를 할 수 잇다.
클래스명ViewController.m에서 shouldAutorotateTointerfaceorientation이라는 메소드를 주석을 풀고 오버라이딩 해 주면 된다. 해당 메소드에는 이미 기본적인 처리방법을 제공하고 있다.

시스템은 특정 방향으로 회전해도 좋은지를 이 메소드를 사용해서 뷰 컨트롤러에게 물어본다. 아이폰을 들고 있는 방향에 따라 일반적으로 4가지 방식으로 응답할 수 있는데, 그에 맞게 방향또한 4가지로 정의되어 있다.

UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight

아이폰 방향이 새방향으로 바뀌면 현재 뷰 컨트롤러의 이 메서드를 호출한다. interfaceOrientation 매개변수는 위의 목록 4가지중 1개의 값을 갖는다. 이 메소드는 새 방향에 맞게 애플리케이션 윈도우가 회전해야 하는지를 알려주기 위해 YES 혹은 NO를 리턴한다.
모든 뷰 컨트롤러의 하위 클래스가 이 방식을 각기 다르게 구현하기 때문에 한 애플리케이션에서 몇개의 뷰에서 자동회전을 지원할 수는 있지만 모든 뷰에 적용할 수는 없다.

이 메소드의 기본구현은 interfaceOrientation을 바라보게 되고 기본적으로 UIInterfaceOrientationPortrait방향에서만 YES를 리턴하게 된다. 이러한 방식으로 애플리케이션 방향을 제한하고 나머지 방향에서는 회전을 사용하지 않는다.
모든 방향에서 회전을 허용하려면 어떤 값이 전달되든지 YES를 리턴하도록 메소드를 변경하면 된다.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

모든 방향을 지원하지 않고 특정 방향만 지원하고 싶다면 interfaceOrientation의 값을 조사해서 지원 하고 싶은 방향에서만 YES를 아니라면 NO를 리턴하면 된다.
예를들어 가로보기 모두를 지원하고 세로보기 거꾸로 뒤집기를 지원하고 싶지 않다면 다음과 같이 구현한다.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

회전할때 뷰를 재구성 해보도록 하자. View-based Application으로 새로운 프로젝트를 시작한다. 프로젝트 명은 Autosize로 하고 프로젝트를 시작하게 되면 기본적인 세팅이 완료된다.
이제 resource를 클릭하여 AutosizeViewController.xib를 클릭하여 인터페이스 빌더를 실행한다.
이와 같이 화면 구성을 만들어 둔다.
 
기본적인 사이즈는 다음과 같다. 가로 125, 세로 125로 적당한 위치에 가이드에 맞춰서 배치해 준다.
AutosizeViewController.h

#import <UIKit/UIKit.h>

@interface AutosizeViewController : UIViewController {
UIButton *button1;
UIButton *button2;
UIButton *button3;
UIButton *button4;
UIButton *button5;
UIButton *button6;
}

@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) IBOutlet UIButton *button2;
@property (nonatomic, retain) IBOutlet UIButton *button3;
@property (nonatomic, retain) IBOutlet UIButton *button4;
@property (nonatomic, retain) IBOutlet UIButton *button5;
@property (nonatomic, retain) IBOutlet UIButton *button6;

@end
 
헤더파일에서 UIButton을 선언해 준다음에 각각의 아웃렛을 설정해 준다. 이는 인터페이스 빌더에서 각각의 버튼에 연결될 것이다.
 
AutosizeViewController.m

#import "AutosizeViewController.h"

@implementation AutosizeViewController

@synthesize button1;
@synthesize button2;
@synthesize button3;
@synthesize button4;
@synthesize button5;
@synthesize button6;


-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation        == UIInterfaceOrientationPortraitUpsideDown){
button1.frame = CGRectMake(20, 20, 125, 125);
button2.frame = CGRectMake(175, 20, 125, 125);
button3.frame = CGRectMake(20, 168, 125, 125);
button4.frame = CGRectMake(175, 168, 125, 125);
button5.frame = CGRectMake(20, 315, 125, 125);
button6.frame = CGRectMake(175, 315, 125, 125);
}else {
button1.frame = CGRectMake(20, 20, 125, 125);
button2.frame = CGRectMake(20, 155, 125, 125);
button3.frame = CGRectMake(177, 20, 125, 125);
button4.frame = CGRectMake(177, 155, 125, 125);
button5.frame = CGRectMake(328, 20, 125, 125);
button6.frame = CGRectMake(328, 155, 125, 125);
}

}
 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}


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

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.button1 = nil;
self.button2 = nil;
self.button3 = nil;
self.button4 = nil;
self.button5 = nil;
self.button6 = nil;
[super viewDidUnload];
}


- (void)dealloc {
[button1 release];
[button2 release];
[button3 release];
[button4 release];
[button5 release];
[button6 release];
    [super dealloc];
}

@end


실제적인 구현부로 버튼들에 대한 synthesize 가 버튼 6개 모드 할당되었다.
회전시에 버튼을 이동시키려면 willAnimateSecondHalfOfRotationFrominterfaceOrientation:duration 메소드를 재정의 해야 한다. 이 메소드는 회전이 일어나면 마지막 애니메이션 동작 전에 호출된다.
버튼과 같은 모든 컨트롤들을 포함해서, 모든 뷰의 크기와 위치가 CGRect 타입의 구조체인 frame이라는 속성에 명시되어 있다. CGRectmake는 CGRect를 쉽게 만들기 위한 애플이 제공하는 함수로서 x, y, 넓이, 높이를 명시하면 CGRect 구조체를 만들어 준다.
CG는 코어 그래픽스 프레임워크라는 이름에서 따온 CG이다. 이름에서 유추할 수 잇듯이 코어 그래픽스 프레임워크는 그래픽스와 드로잉에 관련된 코드들을 제공한다.
 
이제 인터페이스 빌더에서 각각의 아웃렛을 연결하여 준다.
 
 
 
해당하는 버튼의 아웃렛으로 연결하여 주면 모든것은 끝나게 된다.
이제 시뮬레이터로 실행해보면 애니메이션 되는것을 볼 수 있다.
 
 
 
회전하는 방법은 Command + 좌우 방향키로 회전하거나 시뮬레이터 메뉴에서 Hardware 메뉴의 Rotate Left 나 Rotate Right로 할수 있다.
 


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

'아이폰어플개발정보' 카테고리의 다른 글

과제A - Hello Stanford 찍어보기  (0) 2010.06.22
[Objective-C]Autosize 2번째  (0) 2010.06.22
[Objective-C] AutoSize 속성  (0) 2010.06.22
[ObjectiC]액션시트, 경고창  (0) 2010.06.22
[Objective-C] 태그  (0) 2010.06.22
[Objective-C] 아웃렛  (0) 2010.06.22
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:54
[Objective-C] 태그
Interface - Builder

모든 뷰나 컨트롤을 포함한 UIView의 모든 하위클래스들에는 태그 항목이 있는데, 이 항목은 이미지뷰에 할당할 숫자값이고 개발자용으로 고안된 것이다. 즉 시스템은 결코 태그 값을 설정하거나 바꾸지 않는다. 만약 컨트롤이나 뷰에 태그값을 설정하면, 여러분이 바꾸지 않는 한 항상 그 값이라고 확신해도 된다.

태그를 사용하면 쉽고 언어 중립적인 방법(language-independent way)으로 인터페이스의 객체들을 식별할 수 있다. 각기 다른 레이블의 버튼 다섯개가 있고, 버튼 다섯개를 액션 메서드 하나로 다루고 싶다고 해보자. 이런 경우 액션 메서드가 호출됐을 때 어떤 버튼인지 구분할 방법이 필요하다. 물론, 버튼의 타이틀을 확인해도 되지만, 애플리케이션을 한국어나 아랍어로 번역하면 이 코드는 동작하지 않는다. 레이블과 달리 태그는 절대 바뀌지 않으므로, 인터페이스 빌더에서 태그 값을 설정하면 그 값을 액션 메서드에 넘어온 sender 인자가 어떤 컨트롤인지 빠르고 확실하게 확인하는 방법으로 사용할 수 있다.


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

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:54
[Objective-C] 아웃렛

아웃렛은 IBOutlet 키워드를 사용하여 선언하는 인스턴스 변수이다.

컨트롤러 헤더 파일에서 다음과 같이 아웃렛을 선언한다.

@property (nonatomic, retain) IBOutlet UIButton *myButton;

IBOutlet은 컴파일러와 관련하여 아무일도 하지 않는다.  단지 IBOutlet의 목적은 인터페이스 빌더에게 xib(혹은 nib)파일 안의 객체와 연결되는 인스턴스 변수라고 알려주는 힌트를 제공하는 것 뿐이다.

IBOutlet은 전처리문으로 정의되어 있어 이것은 빌드타임에 전처리기에 번역되어 결과는 컴파일러에게 넘겨지게 된다. 다라서 컴파일러는 실제 코드상에서 IBOutlet을 볼 수 없다.

이러한 이유 때문에 인터페이스 빌더 객체와 연결을 원하는 모든 인스턴스 변수 앞에는 반드시 IBOutlet 키워드를 붙여야 한다.

인터페이스 빌더를 열었을때, 인터페이스 빌더는 프로젝트 헤더 파일들로부터 이 키워드를 검색하며 IBOutlet 키워드가 붙은 변수들은 내부 객체와 연결되게끔 도와준다.

nonatomic

멀티쓰레드 환경이 아닌 경우 nonatomic 속성을 지정해서 퍼포먼스를 조금 향상 시킬 수 있다고 한다.

일반적으로 유저인터페이스(UIKit Framework)의 객체에 접근 할 경우 nonatomic 속성을 지정한다.

nonatomic 속성을 지정하지 않으면 디폴트로 멀티쓰레드에서 안전한 접근자(accessors, mutators) 메소드를 컴파일시 생성.

retain

컴파일러에게 이 속성을 통해 할당하는 모든 객체에 retain메세지를 보내게 한다.


이전에는 다음과 같이 IBOutlet을 사용하였다.

IBOutlet UIButton *myButton;

이후 애플에서 제공하는 샘플코드에는 아래처럼 프로퍼티 선언의 다음으로 옮겨졌다.

@property (nonatomic, retain)IBOutlet UIButton *myButton;

두가지 방법 모두 허용되는 방법이며 어떠한 방법을 쓰더라도 큰 차이 없이 동일하게 동작한다.

한가지 차이점이 있다면 인스턴스 변수에 내포되어 있는 이름과 달리 다른 이름의 프로퍼티를 선언하였을경우 반드시 IBOutlet 키워드를 프로퍼티 뒤에 붙여야 정상적인 작동을 한다.



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

댓글을 달아 주세요

XCODE2010. 6. 22. 09:54
[Objective-C] Xcode프로젝트 창

프로젝트를 생성하고 좌측창을 보게되면 다음과 같이 표시가 된다. 내용을 살펴보면 다음과 같다.

* Classes

작성한 대부분의 코드는 여기에 들어가게 된다. Objective-C의 원래 있어야 할 곳이다. 코드 정리를 위해 Classes 폴더 하위로 폴더를 추가 생성해도 된다.

* Other Sources

Objective-C 클래스가 아닌 소스 코드의 위치이다. 새 아이폰 어플리케이션이 제작되면 2개의 파일이 생성된다.

프로젝트명.pch -> 미리 컴파일한 헤더(precomplied header'를 의미하며 프로젝트에서 사용하는 외부 프레임워크의 헤더파일 목록이다.

Xcode에서 이 파일이 담고 있는 헤더들을 미리 컴파일하는데 이렇게 되면 build를 했을경우 컴파일 하는 시간이 줄어든다. 가장 일반적으로 사용하는 헤더 파일들은 이미 포함되어 있기 때문에 신경쓰지 않아도 된다.

main.m -> main() 메소드가 있는곳으로 보통은 수정하지 않는다.(아이폰 어플리케이션에서)

* Resources

애플리케이션의 일부로, 코드가 아닌 파일들을 담고 있다.아이콘, 이미지, 소리, 동영상, 텍스트, 기타 프로그램 수행상의 프로퍼티 리스트 등이 포함된다. 어플리케이션은 각각의 샌드박스에서 실행되므로 필요한 모든 파일을 여기에 넣어야 한다. 이는 허가된API 이외에는 다른곳의 파일에 접근할수 없기 때문이다. 이 폴더에는 기본적으로 3가지 항목이 포함되어 있다.

프로젝트명Controller.xib -> 인터페이스 빌더에 대한 내용을 저장하고 있다.

프로젝트명-Info.plist -> 애플리케이션 정보를 담는 프로퍼티 리스트이다.

MainWindow.xib -> 애플리케이션의 기본 인터페이스 빌더파일이다. 애플리케이션이 간단한경우 보통 손을댈 필요가 없다.

* Framework

코드는 물론 이미지나 소리팡일들과 같은 자원들이 담긴 특별한 종류의 라이브러리이다. 이 폴더에 추가된 프레임 워크나 라이브러리는 애플리케이셔넹 링크되고, 코드에서 그 프레임워크나 라이브러리의 객체, 함수, 자원을 사용할 수 있다. 기본적으로 사용되는 프레임워크들과 라이브러리들은 기본적으로 링크되므로 추가작업은 필요없다. 하지만 추가적인 라이브러리나 프레임워크는 추가 시켜야 한다.

* Products

프로젝트가 생성한 애플리케이션을 담는다. 프로젝트명.app이라는 항목을 볼 수 있는데 이는 프로젝트가 생성한 결과물이다.



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

댓글을 달아 주세요

오브젝트C2010. 6. 22. 09:53
[Objective-C] 클래스
클래스 메소드는 선언시 +를 붙이고 인스턴스 메소드는 -를 붙인다.

클래스 메소드는 Java 나 ActionScript 의 Static 메소드와 비슷한 개념인듯 하다.

클래스 메소드는 클래스 자체로 호출한다.

[Object alloc];

인스턴스 메소드는 인스턴스로 호출한다.
[obj init];

Calculate *myCalculate = [[Calculate alloc] init];
한방에 해결되는 방법.
[Calculate alloc] 이 객체를 리턴한다. 이 자체는 클래스 메소드지만 객체 포인터를 리턴하면서 이것이 init을 호출하므로 init 은 인스턴스 메소드이다. init 역시 객체 포인터를 리턴하며 이는 결국 *myCalculate 에 들어가게 되며 이 변수에 최종적으로 세팅된 객체 포인터가 담기게 된다.


카테고리 개념은 기본 클래스에 메소드만 확장 하는 형태이다. 기존 클래스에 대한 수정 없이 메소드만 추가 가능한다.
선언방법은
@interface 클래스명(카테고리명)
구현부는
@implementation 클래스명(카테고리명)

카테고리 구현부에서는 원래의 클래스에 있는 메소드 및 변수 접근 가능.
기존메소드와 같은 이름의 메소드가 카테고리에 정의되었을 경우 카테고리 메소드가 우선시 된다. 
같은 이름의 메소드가 여러개의 카테고리에 정의 되어 있다면 어느 카테고리의 정의가 사용될 지는 보장할 수 없다.

실험해본 결과 import를 해주지 않아도 구현이 되어 있다면 import에 상관없는 메소드가 호출 되기도 한다.
같은 이름의 메소드를 2개의 카테고리에서 구현하고 1개의 카테고리만 import 한 후 실험했지만 import하지 않은 카테고리 메소드가 수행되었다.
카테고리에 메소드를 정의할 경우 일정한 규칙을 가지고 메소드 명을 만들어야 할것이다.

카테고리의 단점
같은 이름의 메소드가 있다면 사용하지 못한다.
상속인 경우 super 로 상위 메소드를 사용가능 하지만 카테고리는 완전히 오버라이드 되어 버린다.
self 를 호출 할 경우 재귀호출이 되버린다.


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

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

[Objective-C]카테고리 예제  (0) 2010.06.22
[Objective-C]메모리 관리  (0) 2010.06.22
[Objective-C] 클래스  (0) 2010.06.22
[Objective-C]id 에 관하여  (0) 2010.06.22
[Objective-C] 기본 클래스  (0) 2010.06.22
[Objective-C] 1주일 하면서 알아낸 것들  (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 오늘마감

댓글을 달아 주세요

오브젝트C2010. 6. 22. 09:53
[Objective-C] 1주일 하면서 알아낸 것들
Objective-C 할때 맥시스템이 무조건 필요한 것은 아니다.
Objective-C 의 기본요소들은 dev-c++ 이라는 프로그램을 설치하면 확인하며 배울수 있기 때문에 기본 요소들은 Windows 환경에서 해볼 수 있고 iphone sdk 를 작업 해야 할때 그제서야 맥 시스템이 필요하게 된다. 윈도우에서 기본적인 스킬을 익히고 내길이다 싶다면 맥을 지르도록 하자.

메소드 호출은 []로 감싸게 된다.
[object method];
object 란 객체의 method 란 메소드를 호출하게 된다. 기본적인 메소드 호출의 형태이다. 이것은 매개변수가 없는 형태의 호출이고 매개변수가 있는 형태는 다음과 같다.

[object methodWithInput:input];
object 객체에 methodWithInput 이라는 메소드를 input 이라는 값으로 호출하는 것이다. ActionScript 관점으로 본다면
object.methodWithInput(input); 이러한 형태가 될 것이다.

매개변수가 2개 이상인 메소드는 2번째부터 매개변수 명이 붙게 된다.
약간 변태같은 소리같은데 첫번째 매개변수는 이름이 붙지 않게 된다. 
[object initWithMin:0 max:10 step1:];
이러한 상황에서는 object 라는 객체의 initWithMin메소드를 첫번째 인자 0, max라는 인자 10, step이라는 인자를 1이라는 값으로 호출했다. 2번째 부터 인자명이 따로 들어가지만 그렇다고 순서를 섞어쓰면 에러가 나게 된다.
잘 기억할 문제이며 initWithMin이 메소드 명이고 그 이후에는 구분자 없이 단순히 띄워쓰기로 구분한다는 것이다. 그리고 순서도 꼭 지켜야 한다.

할당은 id + alloc
내가 액션스크립트를 주로해서 그런지 id 라는 것에 액션스크립트 키워드 var의 느낌을 느끼게 되었다. id 는 모든 객체의 포인터 정도가 된다. C에서 따지면 void* 정도라는데 어떤느낌인지는 잘 모르겠다.
alloc의 경우 메모리 할당의 과정이다. 간단한 예를 들어 보게 된다면 아래와 같다.
id obj = [[A alloc] init];
id 타입의 obj를 생성했다. id는 모든것이 들어갈 수 있는 포인터같은 개념이기 때문에 obj는 어떠한 객체가 와도 에러를 내지 않는다.
[A alloc] 의 의미는 A 라는 클래스의 인스턴스를 쓰기 위해서 그만한 메모리를 할당 한 것이다. 이는 사용할 만한 공간을 만들고 다음에 추가로 오는 메소드인 init 이 초기화를 해 주는 것이다.
이렇게 되면 obj 라는 변수에 A라는 클래스가 init이라는 메소드를 통해 초기화 하여 들어가게 된다.
여기서 [] 괄호가 2번 중첩되어 사용되었는데 이것은 id 때문에 가능하다. alloc 이라는 메소드는 NSObject의 클래스 메소드로 id 를 리턴한다.
리턴형을 선언하지 않는다면 기본으로 id를 리턴한다고 한다. id를 리턴하게 되면 [A alloc] 이 수행 한 이후 메모리 할당 받은 객체가 리턴되어 바로 [obj init]; 과 같은 형태가 되게 된다. 그래서 []괄호 중첩으로 다수의 메소드를 연속으로 수행 할 수 있게 된다.

클래스 선언은 .h 에서 구현은 .m에서 한다.
ActionScript 에서는 선언과 구현이 동시에 이루어 지지만(interface 제외) Objective-C에서는 선언과 구현이 따로 이루어 지게 된다.
여기서도 Interface라고 명하지만 상당히 다른 의미이다.
@interface A:NSObject 라고 쓰게되면A 라는 클래스를 NSObject를 상속받아 선언하겠다고 하는 것이다. NSObject 는 최상위 클래스로 무조건 1개 이상은 상속 받아야 한다고 한다.
선언이 끝나게 되면 @end라고 써주게 되며 ;는 붙이지 않는다.
이제 구현한다면 @implementation A 라고 써주고 선언한 메소드들을 구현해 준다.
기본 형태는 .h 에서 선언 .m 에서 구현 어디선가 있을 main 클래스역시 .m 으로 구현된다. 확장자가 틀리니 에러가 나버려 확장자에 주의 하여야 한다.
하지만 저렇게 안해버려도 크게 상관 없었다. ActionScript 에서는 클래스명과 파일명이 일치해야 했지만(.as에서 최소 1개는 일치) Objective-C에서는 main.m 하나 만들어두고 거기다가 @interface 로 다수의 클래스를 선언해 버리고 @implementation 으로 다수의 클래스를 구현해 버리고 main 메소드로 시작점 잡아버리면 모든것이 1개의 파일에서 끝나버리는 경우도 있었다. 물론 관리는 개판으로 될듯 하다.



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

댓글을 달아 주세요

오브젝트C2010. 6. 21. 09:31
[Objective-C] 동적으로 메소드 호출하기

Objective-C 의 메소드 호출은 C언어로 정의된 함수 포인터를 호출하는 것과 같습니다.

typedef id (*IMP)(id, SEL, ...);

이 정의로부터도 알 수 있듯이, Objective-C에서 선언된 모든 암묵적으로 id 형태와 SEL 형태의 인수를 가집니다. 첫번째 인자는 메소드를 오브젝트를 나타내는 변수 self 입니다. 두번째 인자는 이 메소드의 selecotr를 변수 _cmd 입니다. 모든 메소드에는 이러한 숨겨진 인자가 반드시 존재합니다.


예를 들어서 사용자가 정의한 +(void) hello { NSLog(@"hello, World!!"); } 라는 메소드를 호출을 하게 되면 내부적으로 아래와 같이 호출이 됩니다.


func(self, @selector(hello));     // 여기서 func는 IMP 타입의 함수 포인터

그리고 사용자는 NSObject 클래스의 메소드인 instanceMethodForSelector를 통해서 IMP 타입의 함수 포인터를 얻을 수 있다.

(이 밖에도 여러 가지 메소드가 있음, 자세한 것은 API 참조..!!)


IMP func = [ClassName instanceMethodForSelector: @selector(hello)];

이렇게 얻은 IMP 값은 앞서 설명했던 것처럼 함수 형태로 호출이 가능하다.

첫 번째 매개변수는 호출한 메소드를 정의한 클래스 객체이고, 두 번째 매개변수는 해당 메소드의 셀렉터이다.


만약에 호출할 메소드가 매개변수를 포함하고 있다면, 아래 예제와 같이 해당 인자 값을 세 번째 매개변수로 입력하면 된다.


// 앞서 정의했던 hello 메소드가 아래와 같이 param 매개변수가 있을 경우,

// +(void) hello : (NSString *)param { NSLog(@"Hello, %@", param); }

// ...

func(self, @selector(hello:), @"Mr.Hong");

func함수는 세 번째 매개변수부터 가변적으로 입력할 수 있으므로, 셀렉터를 통해 얻은 메소드의 매개변수에 맞게 값을 입력하면 된다.
그리고 IMP 함수 포인터를 사용하지 않고, NSObject 클래스에 정의된 performSelector 메소드를 사용하면 바로 호출이 가능하다.

[self performSelector: @selector(Hello)];

performSelector 메소드는 IMP 함수 포인터를 사용하는 것과 달리 가변 인자를 지원하지 않음으로써 매개변수가 다수 일 경우에 제약이 따른다. 하지만 메소드 호출 지연 등 여러 옵션을 주어 보다 다양한 방법으로 사용할 수 있다.

[self performSelector: @selector(Hello) withObject:nil afterDelay:1.0f];
여기서 afterDelay는 해당 메소드를 호출하기까지 지연되는 시간(단위/초)이이며, withObject는 호출하는 메소드의 매개 변수 값이다.

iPhone 어플리케이션 개발을 하다 보면 델리게이트 메소드를 사용하는 경우가 많은데, 현재 동작하고 있는 델리게이트가 많을 경우에 메소드 호출 순서가 약간은 생각했던 것과 다를 수도 있다. 그런 경우에 performSelector를 사용하여 메소드 호출 시점을 조정할 수 있다.

이렇게 Objective-C에서는 동적으로 메소드를 호출할 수 있는 방법이 두 가지가 있다. 매개변수의 수가 많거나 타입이 Object가 아닐 경우에는 IMP 함수 포인터를 사용하면 되고, 메소드 호출의 지연 시간을 정하고 싶다면 performSelector 메소드를 사용하면 될 것이다.







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

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

[펌] Delegate  (0) 2010.06.21
[펌] Key-Value Coding  (0) 2010.06.21
[Objective-C] 동적으로 메소드 호출하기  (0) 2010.06.21
[펌] 메소드의 포인터, IMP란?  (0) 2010.06.21
[펌] Objective-C 생성자  (0) 2010.06.21
[강좌] From C++ to Objective-C  (0) 2010.06.21
Posted by 오늘마감

댓글을 달아 주세요