너는 누구냐.

아.. 두부냄새.

Archive for the ‘코코아’ Category

공사가 반쯤은 끝난 DokDo.

without comments

DokDo가 완성단계에 이르렀다. 지난번 Tok도 독도에서 이름을 따 온것인데, 톡보다는 아예 독도 그대로가 낫겠다 싶어, 독도로 개명을 시켜줬다. 지난번 보다 확장이 쉽도록 (코드) 디자인을 바꿔줬고, 전에 안써봤던 NSViewController도 이번에 써 봤다.

marsEdit이나 ecto가 성에 안차서 독학하며 만들기 시작한 Tok이었는데, 꽤많이 발전한것 같다. 이제는 ecto에서도 오프라인에서 이미지를 포함하는 포스트를 원활히 쓸수 있다지만, 여러개의 창을 써야하는 marsEdit 이나 ecto는 여전히 마음에 들지 않는다. 그래서 DokDo는 단일윈도우에서 모든것을 다 소화… 마우스가 (거의) 필요없는 블로깅 툴로 만들었다. 아마 조금씩 시간이 가면서 마우스를 아예 쓸필요가 없는 녀석으로 만들어갈것 같다.

Written by dglee2

February 9, 2009 at 12:05 am

Posted in 컴퓨터, 코코아

Tagged with ,

장난감 또 하나.

without comments

장난감을 또 하나 만들었다. 장난감 이름은 DON. 돈이다. 돈을 어디에 얼마를 썼는지 쓴것만 관리해주는 초간단 유틸이라 하겠다. Core Data는 이제 더이상 손대지 않으려고 하다가… 어젯밤에 잠이 안오는 관계로 두시간 만지작 거렸더니 반정도 완성.. -_-;; 끝내지 않으면 괜히 헛짓거리 한것 같아서 오늘 초간단 ‘주말 프로젝트’로 완성을 시켜버렸다.

앞으로 추가 하고 싶은 것은 iCal 연동 기능과 챠트/그래프 기능. iCal db는 어떻게 접근하는지 전에 해봤기때문에 알고 있는것이고.. 역시 챠트나 그래프는 Quartz Composition을 활용하고 싶은데.. 어찌 챠트는 만들게 될까 말까 모르겠다.

Written by dglee2

August 31, 2008 at 7:22 pm

Posted in 코코아

Tagged with ,

XIB와 NIB

without comments

조금전 포스트에 언급한것과 같이 cocoadev.co.kr을 둘러봤을때 XIB에 관한 포스트가 있어 간단히 읽어봤다. 그런데 XIB가 XML형태라는것 외에는 별다른 내용이 없는것 같아 이쪽.. 내 블로그에다 약간 첨언하고자 한다.

XIB는 Xcode 3.1이 되면서 새로 생긴것이 아니라 사실 Xcode 3.0에서부터 있어왔다. XIB는 coocadev.co.kr에서 말한대로 XML 형태의 파일이다. 그런데 왜? 왜 가만히 잘있는 NIB을 XIB로 바꿨을까?

애플이 호환성 문제로 가장 골치아파 하는것중 하나가 바로 이 Bundle이다. HFS에서 지정하는 metadata가 있어야 제대로 인식되고 사용되는 이 Bundle이 왜 새삼 문제가 되는가 하면.. 비슷한 형태의 응용프로그램과는 다르게 Bundle은 소스코드의 일부분이라는것이다. 소스코드의 일부분이기에 Subversion과 같은 SCM을 통해 웹에 업로드되어야 하고 다운로드 받아야 한다는것. 그런데 결정적인 골칫거리는 웹을 왔다갔다 하면서 Bundle의 metadata가 호환성의 문제로 없어질수도 있다는것이다. 해서 애플에서 부랴부랴 XML형태의 flat file인 XIB 포맷을 만들어낸것이다.

XIB와 NIB은 100% 같다고 보면 된다. 물론 개발자에게만. NIB의 한가지 단점은 응용프로그램으로 만들어지고 난 뒤 해커? 들에 의해 마음대로 수정될수 있다는것이었다. 몇몇 애플 응용프로그램이 가진 NIB파일은 compile되었다면서 Interface builder에서 로딩하지 않지만, 대부분의 맥 응용프로그램이 포함하고 있는 NIB파일은 언제든지 수정가능한 형태로 배포되는것이 사실이다.

그렇지만 응용프로그램 번들에 포함되어 있는 XIB는 열리지 않는다. 응용프로그램이 일단 컴파일 되면 Interface Builder에서 열어볼수가 없는것이다. 개발자로서는 반가운 소식이라 생각되는데, 아무튼 그렇다. 개발자로서 XIB 사용을 회피해야 할 이유는 NIB보다 파일사이즈가 ‘아주’약간 커진다는것. XIB를 쓰지 않을 이유는 사실상 없는것이다.

Written by dglee2

August 28, 2008 at 11:05 pm

Posted in 코코아

Tagged with , ,

Quartz Composer

without comments

Xcode Tools중 Xcode 다음으로 가장 좋아하는.. (잘다룬다는 것이 아니라.. 단순히 좋아하는..) 툴이 바로 Quartz Composer다. Quartz Composer를 가지고 놀다보면 눈앞에 펼쳐지는 신기함에 시간가는줄을 모르기 때문이다.

Quartz Composer를 매번 들여다 보는 또다른 이유는, 화면 보호기를 만드는것은 물론 코코아 응용프로그램에서도 요긴하게 사용할수 있기때문이다. 아이폰 응용프로그램 에서도 역시 Quartz Composition을 사용할수 있으니 조금씩 조금씩 놀아가며.. -_-;; 배워놓으면 나중에 다 피가되고 살이되리라는 생각이 있다.

물론 코코아에서 composition을 불러다 사용하는 기본적인 방법은 이미 터득한지 오래다. 정작 문제는 스스로 쓸만한 composition을 만들어내는 단계에 오르려니 이거 꽤나 힘들다. 머리가 나빠서일수도 있고.. 창의력이 없는 굳어버린 감각 때문일수도 있겠지만.. 굳이 핑계를 대자면 예제파일을 들여다 볼때마다 매번 입맛이 뚝뚝 떨어지게하는 Ugliness덕분인것 같다.

Ruby 개발자왈 Perl이 Ugly하다 했다. 그렇지만 Quartz Composer는 단순한 ugliness를 넘어서 적어도 나에게는 험오감마져 주는듯 하다. 매번 붙잡고 갖고 놀다가.. 어떻게 만들었나 좀 배워볼까? 하면 헉. 하는 소리가 나오며 딱 쳐다 보기가 싫어지니.. -_-;; 도대체 언제 득도를 할지 까마득하기만 하다. 제발 애플에서 이것좀 이쁘게 만들어주면 안될까?

Written by dglee2

August 27, 2008 at 12:59 am

Posted in 코코아

Tagged with

NSInteger

without comments

10.5 SDK를 사용하면서 문득 NSInteger가 뭐야.. 하는 경우가 있을것이다. NS가 붙었지만 class 이름은 아니다. 자바에서는 각각 primitive value마다 class를 만들어놨기 때문에 NSInteger도 역시 class가 아닌가 할수도 있겠지만, 보다시피 NSInteger는 시스템이 64비트를 지원하는가에 따라 값이 달라지는 단순한 C 매크로다.

#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

따라서 자기가 가지고 있는 시스템이 둘중 어느것인지 알아보는 방법은.. 다음과 같다.

	NSLog(@"%d,%d",INT_MAX, INT_MIN);
	NSLog(@"%d,%d",LONG_MAX, LONG_MIN);
	NSLog(@"%d,%d,%u",NSIntegerMax, NSIntegerMin, NSUIntegerMax);

#if __LP64__ || NS_BUILD_32_LIKE_64
	NSLog(@"64");
#else
	NSLog(@"nah");
#endif

Written by dglee2

August 19, 2008 at 10:19 pm

Posted in 코코아

Tagged with

Collection Object: 정렬하기

without comments

NSArray에서 정렬하는 방법이다. 코코아의 Collection Object들은 수학적인 개념을 그대로 옮겨놓은것이기 때문에 Array를 제외하고는 정렬할수가 없다. NSSet은 원래 순서가 없는것이며, NSDictionary 역시 Key와 Value 짝이 NSSet에서와 같이 순서없이 뒤섞여 있다고 생각하면 된다.

아래 코드에서는 숫자 3,3,5를 가진 NSArray를 만든뒤, 다시 Set로 변환시킨다. NSSet은 원래 순서를 따지지 않기때문에 description을 사용해서 볼때마다 순서가 3,3,5로 나올수도 그렇지 않을수도 있다. 아무튼, 그런 Set에 있는 숫자를 다시한번 NSArray형태로 집어 넣은뒤 정렬하고 있다. 참 멍청한짓 같지만, 아무튼 @selector()에 익숙해지는것이 좋다.

	NSArray *array = [NSArray arrayWithObjects:
					  [NSNumber numberWithInt:3],
					  [NSNumber numberWithInt:3],
					  [NSNumber numberWithInt:5],nil];
	NSSet *set = [NSSet setWithArray:array];
	[array release];
	NSMutableArray *marray =
		[[NSMutableArray alloc] initWithCapacity:[set count]];
	for(NSNumber *num in set)
		[marray addObject:num];
	[marray sortUsingSelector:@selector(compare:)];
	NSLog([set description]);
	NSLog([marray description]);
	[marray release];

보는것과 같이 정렬하는것은 상당히 간단하다. 위 코드에서는 숫자를 정렬하는것이기 때문에 @selector(compare:)를 사용했지만, Array가 가지고 있는 Object가 String일 경우에는 compare: 도 좋지만 String이 영문이 아닐경우를 대비해 localizedCompare:를 쓰는것이 조금더 안전하다.

compare:는 NSObject으로 부터 상속받는 method로 새로운 Object를 만들때마다 Overload할수 있다. (하는것이 좋다.) NSString역시 compare:를 overload해 놓았고, 또다른 method, localizedCompare:까지 만들어 놓은것이다.

Compare:를 overload하는것은 의외로 쉽다. 예를들어 Person class의 compare:를 오버로드 한다고 할때 이름으로 정렬하기를 원한다면 이름이 담긴 string 인스턴스 변수의 compare:나 localizedCompare:의 값을 리턴하면 된다.

Written by dglee2

August 19, 2008 at 10:07 pm

Posted in 코코아

Tagged with ,

메모리 누출

without comments

한참 복잡한 코드를 작성하고 나면 아마 마무리 단계에서 꼭 해야될것이 메모리 leak이 있는지 확인하는 일일것이다. Xcode Tools에는 Instrument라는 여러가지 도구들이 있어 메모리 유출이 있는지 비교적 손쉽게 테스트 해볼수 있다.

그런데 문제는… 누가 그랬는지는 모르겠지만, coder들은 다들 게으르다 했는데 정말 그말이 맞는것 같다. 나도 coder의 반열에 올라섰는지 웬지 이 Instrument라는 것에 익숙해지기 귀찮기만 하다. 겉으로 보면 손쉽게 사용할수 있을것 같은데.. 정작 뭘좀 하려면 documentation을 또 꼼꼼히 읽어내려가야 하기 때문이다.

Instruments에서 메모리 누출을 검사하는 것에 상응하는 command-line 응용프로그램은 leaks다. 정말 직관적인 이름이다. command-line에서 leaks를 실행시키면 사용방법이 나오기도 하지만, leaks의 사용방법은 정말 간단하다. leaks 뒤에 argument로 process id를 적어주면 끝이다. process id를 어떻게 알아내느냐고? -_-;; 흠.. 그것까지 말해줘야 할까.

아무튼, leaks를 사용하기 위해서는 응용프로그램이 종료되면 안되기때문에 (다시한번 말하지만, process id가 필요하다) command-line 응용프로그램일 경우엔 마지막에 무한루프를 돌리거나 하는 방법으로 프로그램을 계속 살려두는 것도 좋은 방법이다. 한가지 주의할점은 leaks가 메모리 유출을 판단하는 기준은 더이상 메모리를 해제해줄수 없는 메모리 할당값을 찾는것이다. 따라서, 예를들어 메인 함수에서 메모리를 할당, 해제 하지 않은 상태에서는 leaks가 말해주는것은 메모리 누출이 없다는 것. 당연히 메인 함수 내에서 메모리를 해제시킬수 있는 가능성이 남아 있기때문이다.

Written by dglee2

August 18, 2008 at 9:32 pm

Posted in 코코아

Tagged with ,

Objective-C 메모리 관리법

without comments

Objective-C 2.0에서는 Java와 유사한 Garbage Collector를 사용할수 있기때문에 메모리 관리를 아예 해주지 않아도 괜찮다. 그렇지만 할려면 해줄수도 있다. -_-;; Garbage Collector에 의존하는것도 좋지만, 손수 관리를 해주면 아무래 성능면에서 이득을 볼수 있기 때문이다.

Objective-C가 사용하는 기본적인 메모리 관리법은 reference counting이다. 내부적으로 할당된 메모리를 참조하는 곳이 몇군데인지 숫자를 매겨 더이상 참조하는곳이 없을 경우에 메모리를 최종적으로 해제시키는 방법이다. 개인적인 생각으로는 언제든지 메모리를 해제시킬수 있기때문에 항상 메모리를 해제시켜도 되는지 확인해야하는 C/C++와 메모리 할당/해제를 할수 있는 권한? 을 아예 박탈시켜놓은 Java사이의 적절한 절충안인것 같아 입맛에 맞는것 같다. (맞는지는 모르겠지만 얼핏 기억으로는 Ruby또한 reference counting을 이용한 garbage collector를 쓴다고 한다.)

코코아/Objective-C 메모리 관리는 몇가지 규칙만 알아두면 의외로 간단하다. 첫번째는 메모리를 할당한곳에서 역시 메모리 할당을 해제시키라는것, 두번째는 메모리를 할당하는 코드를 썼을경우에만 메모리 해제의 책임이 있다는것. 생각해보니 몇가지가 아닌 이것 두가지만 외우고 충실히 따르면 코코아 메모리 관리는 끝난것 같다.

메모리 할당은 alloc, copy, retain method를 사용했을경우 일어난다. 물론 세가지 method중 하나를 사용했다면 해당 procedure가 끝나기 전에 release나 autorelease를 해줘야 한다. 메모리 해제하는 방법은 본것과 같이 release와 autorelease가 있는데, autorelease이것은 어찌보면 garbage collector의 전신인것 같기도 한게 나중에 자기가 알아서 release시켜주라는 뜻이다. 물론 release는 명령어를 실행시키자 마자 메모리 할당을 해제시키라는 것.

쓰고보니 약간 헷갈리게 쓴것 같기도 한데, 진짜 메모리 할당은 alloc이나 copy를 부를때 일어나고 그 뒤 retain을 할 경우엔 해당 메모리에 대한 reference count를 증가시키게 된다. 반대로 release나 autorelease를 사용하면 해당 메모리에 대한 reference count를 증감시키게 되는데, 증감후의 값이 0이라면 시스템이 할당된 메모리를 해제시키게 되는것이다. 따라서 reference count를 올려놓기만 하고.. 다시 감소시키지 않으면 시스템은 어디에선가 메모리값을 참조하고 있다고 판단하여 메모리를 해제시키지 않는다. 당연히 메모리 누출이 일어나고 해당 응용프로그램은 점점더.. 몰락-_-;; 의 길로 빠져들게 되는것.

그렇다면 언제 retain 해줘야 하는가. parameter값으로 넘겨받은 값은 해당 procedure내에서는 그 값이 그대로 유지된다. 해당 procedure에서 값을 넘겨받고 버릴것이라면 retain할 필요가 없다. 그렇지만 같은 class내 다른 procedure에서도 그 값을 필요로 하는 경우라면 retain이나 copy를 해둬야 한다.

간혹 헷갈리는 경우는 factory 함수를 사용할때. factory 함수는 autorelease되는 object을 넘겨주기때문에 따로 release해주지 않아도 된다. (해주면 나중에 에러난다…) NSArray와 같은 collection object들은 addObject과 같은 함수를 사용하거나 처음 생성될때 받는 object를 알아서 retain 하기때문에 ‘통’에다 집어넣고는 버려(release)도 괜찮다. Collection Ojbect외에도 parameter로 받는 값을 retain하는 애들이 다수 있으니 그때그때 문서를 참조하면 된다.

Written by dglee2

August 18, 2008 at 8:56 pm

Posted in 코코아

Tagged with ,

코코아 프로그래밍 시작하기

without comments

아마도 코코아 프로그래밍 입문을 하면서 저지를수 있는 실수 중 하나는.. 힐리가스의 책만을 믿고 그것만 들여다보는 일일지도 모르겠다. 나 역시 2차, 3차 개정판을 다 읽었지만 그때마다 그것으로는 턱없이 부족하다는것을 느꼈었다.

가장 큰 문제점은 힐리가스의 책은 처음부터 AppKit을 가지고 논다는것이 아닐까 싶다. 물론 윈도우를 만들고 어쩌고 하는것이 눈에도 즐겁고 재미있어 보이지만, 이래저래 따라하다 보면 몇가지를 제외하고는 모두 응용프로그램의 껍데기 만드는 법만 설명한다는 느낌을 받는 사람이 나뿐만이 아닐듯 싶다.

AppKit은 코코아의 일부분일 뿐이다. 정작 코코아를 이용해 무언가를 하는 값어치 있는 응용프로그램을 만들고자 한다면 AppKit보다는 Foundation framework을 좀더 공부 하는것이 중요하다. 물론 UI개발에 매달리는 사람이라면 AppKit으로 만족할지도 모르겠지만, UI개발을 한다 해도 Foundation Framework를 원활히 사용하고자 할것은 너무나도 뻔한일이다. 이름 그대로 튼튼한 기반없이는 껍데기 꾸며봤자 별 소용이 없다는 것이다.

Written by dglee2

August 18, 2008 at 2:14 pm

Posted in 코코아

Tagged with ,

NSPredicate

without comments

CoreData 프레임워크를 사용하다 보면 필수적으로 맞닥뜨리게 되는것이 NSPredicate이다. 처음 사용법을 익히기가 조금 까다로울지 모르겠지만, 의외로 사용법이 간단하고 알아두면 여러모로 쓸모가 많은것이 바로 NSPredicate이다.

CoreData FetchRequest를 작성할때 NSPredicate을 사용하기도 하지만, 여기서는 조금더 일반적인 경우. 레오파드에서 새롭게 추가된 filteredArrayUsingPredicate의 예제를 간단히 만들어 보았다. 아마 아래코드를 이해한다면 여러가지 방법으로 교집합, 합집합을 구하거나 Collection 세트에 들어있는 객체에 대한 구제척인 검색을 할수 있을것이다.

	NSMutableDictionary *_one = [[NSMutableDictionary alloc] init];
	NSMutableDictionary *_two = [[NSMutableDictionary alloc] init];

	int n;
	for (n=0; n<10; n++){
		[_one setValue:[NSNumber numberWithInt:n]
				forKey:[NSString stringWithFormat:@"key%d",n]];
		[_two setValue:[NSNumber numberWithInt:n+5]
				forKey:[NSString stringWithFormat:@"key%d",n]];
	}

	NSArray *_array = [NSArray arrayWithObjects:_one, _two, nil];
	NSLog([[_array filteredArrayUsingPredicate:
		[NSPredicate predicateWithFormat:@"key4==9"]] description]);

	[_one release];
	[_two release];

Written by dglee2

August 18, 2008 at 1:07 am

Posted in 코코아

Tagged with