<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Eonil&#039;s Blog</title>
	<atom:link href="http://blog.eonil.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.eonil.com</link>
	<description></description>
	<lastBuildDate>Tue, 26 Jul 2011 19:14:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>광고 기반 시장과 UX</title>
		<link>http://blog.eonil.com/post/837</link>
		<comments>http://blog.eonil.com/post/837#comments</comments>
		<pubDate>Mon, 25 Jul 2011 00:57:22 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Think]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=837</guid>
		<description><![CDATA[오늘 까소봉님의 번역을 읽다가 평소에 하던 생각과 크게 공감이 되어서 해당 게시판과 여기에 크로스포스팅합니다. 감독 대 위원회, 애플 대 구글 구글의 문제는 위원회라기보다는 그냥 최종 보스가 UX에 대한 개념이나 취향 자체가 없다는 거죠. 그래서 그것을 중요하게 생각하지 않고, 그 분야에 뛰어난 사람을 가릴 수도 없을 뿐더러, 설령 좋은 사람이 있다 해도 높은 권한을 주지 않습니다. [...]]]></description>
			<content:encoded><![CDATA[<p>오늘 까소봉님의 번역을 읽다가 평소에 하던 생각과 크게 공감이 되어서 해당 게시판과 여기에 크로스포스팅합니다.</p>
<p><a href="http://www.appleforum.com/mac-column/60711-감독-대-위원회-애플-대-구글.html#post532019" title="감독 대 위원회, 애플 대 구글">감독 대 위원회, 애플 대 구글</a></p>
<p>구글의 문제는 위원회라기보다는 그냥 최종 보스가 UX에 대한 개념이나 취향 자체가 없다는 거죠. 그래서 그것을 중요하게 생각하지 않고, 그 분야에 뛰어난 사람을 가릴 수도 없을 뿐더러, 설령 좋은 사람이 있다 해도 높은 권한을 주지 않습니다. 디자인 측면에서 보자면, 생각보다 평범한 기업이라 볼 수 있습니다. 보스가 좋은 취향을 가지는 기업이라는 것 자체가 희귀하니까요. 혹시 미니멀리즘적 취향을 갖고 있을지는 모르겠지만, 광고 기반 제품에서 그 취향을 살리는 건 불가능합니다.</p>
<p>굳이 구글에 한정하지 않더라도 대부분의 하드코어 컴퓨터 공학자는 정말로 UX에 대한 개념 자체가 없습니다. 대부분의 경우 공학자는 그냥 현재 있는 환경에 자신을 짜맞추는 사람들이죠. 그들은 수학같은 추상적인 세계에서 아름다움을 느끼고 현실 세계의 아름다움은 느끼지 못합니다. 언어의 문법에는 호불호가 갈리지만, Mac OS X와 Ubuntu의 차이점은 발견하지 못하죠. 그래서 자신을 변화시키기 싫어하고, 구체적인 &#8220;취향&#8221;을 가지는 일반 사용자의 마음을 전혀 이해하지 못합니다. 뛰어난 개발력을 갖고 있으면서도 최종 사용자용 제품에서는 항상 밀릴 수 밖에 없는 이유가 그거죠.</p>
<p>구글 보스의 마인드가 바뀌지 않는 한 구글의 UX는 나아지지 않을 겁니다. 하지만 구글 보스는 정말로 뛰어난 하드코어 공학자라 바뀔 가능성이 거의 없습니다. 한 개인의 삶을 모두 분석하면 인간의 기분과 취향을 측정하는 것도 가능할 지도 모르지만, 프라이버시가 있는 이상 사용자들이 그것을 거부할 거구요. 과학적으로 &#8216;가능&#8217;한 것이 그게 도덕적이라는 것을 의미하지는 않으니까요. 혹시 그가 바뀌더라도 그는 자신의 밑에 있는 다른 뛰어난 공학자들을 설득할 수 없을 겁니다. 구글의 UX가 좋아진다는 것은 구글이 뛰어난 개별력을 잃어버린다는 뜻입니다.</p>
<p>구글에서 페이스북으로 옮겨갔다는 그 디자이너는 다음 직장도 잘못 고른 것 같군요. 페이스북은 구글과 똑같은 기업입니다. UX따윈 안중에 없어요. 페이스북이 구글과 다른 점이라면 마케터와 클라이언트 파트 개발자의 힘이 좀 더 세다는 것 뿐입니다.</p>
<p>구글이나 페이스북이나 초기진입을 잘 해서 시장을 독점하고 있으므로 장사가 되는 것이지 UX가 좋아서 장사가 되는 것이 아닙니다. 대부분의 경우 광고 기반 시장은 애초에 UX라는 것을 기대할 수가 없는 분야이기에 단순히 기술력으로 효율을 극대화한 주자가 리드를 하게 되더군요. 또한, 광고 기반이라는 그 자체가 UX에 한계를 가진다는 뜻이므로 정말로 뛰어난 디자이너는 가능한한 광고 기반 제품에 참여하지 않으려 합니다. 트위터의 UX가 구글/페이스북보다 좋은 것은 그것이 광고에 기반하지 않기 때문입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/837/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>개발자들이 탈옥을 지지한다?</title>
		<link>http://blog.eonil.com/post/798</link>
		<comments>http://blog.eonil.com/post/798#comments</comments>
		<pubDate>Tue, 19 Jul 2011 17:46:54 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=798</guid>
		<description><![CDATA[인터넷을 노닐다 어떤 포스트를 접하게 되었습니다. 큰 무리없는 내용이지만 본문에 오류가 하나 있어서 답글을 적다 포스팅까지 하네요. http://ithings.kr/357 저는 이 포스트를 공격할 의도는 전혀 없습니다. 단지 문제가 있어 보이는 한 문장만 꼬투리를 잡고 싶을 뿐입니다. 일단 문제가 있는 부분은 이 부분입니다. 많은 개발자들이나, 개발자를 꿈꾸는 사람들은 &#8220;탈옥된 아이폰이나 아이패드가 순정 만큼이나 안전하다&#8221;고 주장한다. 또한 이러한 [...]]]></description>
			<content:encoded><![CDATA[<p>인터넷을 노닐다 어떤 포스트를 접하게 되었습니다. 큰 무리없는 내용이지만 본문에 오류가 하나 있어서 답글을 적다 포스팅까지 하네요.<br />
<a href="http://ithings.kr/357">http://ithings.kr/357</a></p>
<p>저는 이 포스트를 공격할 의도는 전혀 없습니다. 단지 문제가 있어 보이는 한 문장만 꼬투리를 잡고 싶을 뿐입니다.<br />
일단 문제가 있는 부분은 이 부분입니다.</p>
<blockquote><p>많은 개발자들이나, 개발자를 꿈꾸는 사람들은 &#8220;탈옥된 아이폰이나 아이패드가 순정 만큼이나 안전하다&#8221;고 주장한다. 또한 이러한 주장은 기술적 이유를 바탕에 두기 때문에 언뜻보면 사실처럼 보인다.</p></blockquote>
<p>이 문장은 언뜻 보면 개발자들이 탈옥을 지지하는 것처럼 들립니다. 자세히 보면 좀 다르긴 하지만요.<br />
여튼, 제 생각은 이렇습니다.</p>
<blockquote><p>개발자들은 탈옥을 좋아하지 않습니다.</p></blockquote>
<p>탈옥을 하면 (1) 시스템에 예측할 수 없는 변경사항이 생기므로 (2) 예측할 수도 테스트할 수도 없는 에러가 생기고 (3) 이 에러는 재현 및 검증할 수 없기 때문에 없앨 수 없습니다. (4) 하지만 탈옥 사용자도 고객이므로 무시할 수 없고, (5) 결국 예측 불가능한 버그를 잡아야 하는 불가능한 일을 해야 합니다. (6) 불가능한 것을 가능하게 하는 것은 불가능하거나, 부분적으로만 가능하며, (7) 부분적으로 가능하다 하더라도 예측 가능한 환경에 비해 매우 높은 (몇배 이상) 비용이 듭니다. </p>
<p>개발자든 개발사 사장이든 거기에 돈대는 투자자든 이러한 환경을 좋아할 이유가 없습니다. 케이스 바이 케이스로 문제가 생길 때마다 고치려 시도해 볼 수 있겠지만, 문제를 재현하기가 거의 불가능하므로, 문제를 고칠 수 없고 결국 원인이 아닌 증상만 제거하게 됩니다. 물론 의학에서와 같이 이러한 것은 궁극적인 해결책이 되지 못하며, 문제가 재발하거나, 다른 문제가 생기는 원인이 될 뿐입니다. </p>
<p>탈옥 지지자들이 어떤 기술적인 이유를 대는지 모르겠지만, 그러한 이유가 설득력 있다고 평가된다는 것이 &#8220;전문용어 현혹&#8221;이라는 스킬이 사기인 이유입니다. 물론 탈옥을 지지하는 사람들은 있습니다. 하지만 제가 보기엔 그들은 이들 중 하나입니다. (1) 제품의 품질을 자신이 책임지지 않아도 되는개발자 (2) 수준이 매우 떨어지는 개발자 (3) 그냥 자기가 만든 프로그램을 자기가 쓰려는 개발자 (4) 개발자가 아닌 취미가.</p>
<p>#1은 대부분의 경우 &#8216;취미&#8217;앱 개발자입니다. 취미인만큼 책임감도 전혀 없습니다. 가끔 매우 크리에이티브한 작품이 나오기도 하지만, 대부분의 경우 책임을 지는 일은 없습니다. 되면 되고 안되면 마는 거죠. 제품이라기보다는 거의 예술 작품에 가깝습니다. 물론 여기에 지불하는 사람도 있으나 그 규모는 산업으로 유지할 수는 없는 규모입니다. 오픈소스 쪽에 이런 사람들이 많은데, 왜냐면 오픈소스 외에는 이런 사람들이 나설 곳이 없기 때문입니다. 아 오해는 마세요. 모두가 그런것은 아닙니다. 일부 오픈소스 개발자들은 자신의 작품에 큰 책임감을 갖고 있으며, 장인정신이라 부를수 있을만한 굉장한 작품을 만들어 냅니다. 하지만 이경우, 높은 비율로 대기업(애플, 오라클, IBM, 구글, 소니 등등을 말합니다.)의 관련 프로젝트 컨설턴트로 활동하면서 상당한 규모의 서포트를 받게 되니 무료 개발자라고 하기는 힘들더군요.</p>
<p>#2는 책임감은 있지만, 품질의 개념이 없거나 제대로 이해하지 못한 개발자입니다. 기능을 만들 줄만 알지, 문제가 생기리라고는 상상조차 못하는 초보입니다. 사실 프로 개발자라고 부르기에는 이른 단계입니다. 최근들어 여러가지 이유로 인해 이 단계에 있는 사람이 많아졌죠. 주로 웹/마케팅쪽에 이런 사람들이 많습니다. (동어반복인가요? :) HTML은 원래 앱을 위한 것이 아니기에 정확하게 만들 수 없으며, 대충 만들어서 대충 돌아가도록 디자인되어 있거든요. 물론 대충 쓰면 상관없지만, 대충 문제가 생기면 대충 참는 수 밖에 없습니다. 물론 HTML의 한계를 파악하고 그 한계를 정확히 지켜서 완벽한 앱을 만들어내는 사람도 있지만, 찾아내는 것이 거의 불가능할 정도입니다. 하여튼, 이 단계에 있는 사람들이 저지르는 대표적인 실수는 &#8216;암호화 없는 로그인 시스템&#8217;이라든가 &#8216;바꿀 수 없는 아이디&#8217;, &#8216;클릭이 안되는 위치에 있는 버튼&#8217;, &#8216;찾을 수 없는 메뉴&#8217;, &#8216;마지막 단계에서 처음으로 무한 반복되는 기능&#8217;, &#8216;취소도 불가능한 주제에 뭘 누를 때마다 기다려 달라는 앱&#8217; 같은 것들입니다. 어떻게든 뭘 만들어내긴 하지만, 쓸만한 물건은 못만들어냅니다. 사실 이건 이들의 문제라고는 볼 수 없습니다. 이런 저질 제품에 값을 치르는 사람들이 있거든요. 덕분에 우리가 싸구려 프로그램들 사이에서 고통받고 허덕이고 있는 것이지요.</p>
<p>#3. 뭐 자기가 쓰겠다는데 뭐라할 이유는 없겠죠.</p>
<p>#4는 제가 잘 모르겠네요. 탈옥폰은 왜 뱅킹/결제 지원안하냐고 투덜대는 사람들이 있는가 하면, 탈옥의 위험을 잘 알고 조용히 쓰는 사람들도 있습니다.</p>
<p>탈옥을 지지한다면 아마추어 프로그래머일 뿐, 프로 개발자라고는 할 수 없습니다. 최소한 자신이 만든 제품의 품질에 책임을 저야 하는 입장에서 탈옥은 지옥체험일 뿐입니다. #3같은 경우는 책임을 질 필요가 없다는 점에서 그 순간만큼은 아마추어 개발자가 되는 겁니다.</p>
<p>그런데 왜 개발자가 탈옥을 원한다는 이야기가 나오느냐? 그건 빈 깡통이 요란하기 때문입니다. 시스템 환경 제약 조건의 필요성을 아는 사람들은 조용히 제작을 할 뿐 거기에 대해 불평하지 않습니다. 불평할 일이 없죠. 제조사가 대신 욕먹으면서 개발하기 좋은 환경을 조성해줬으니까요. 하지만 #1 및 #2 사람들은 불만이 대단합니다. 게다가 이런 사람들일수록 자신이 대단한 개발자인양 행세합니다. 멀리서 보면 이사람들의 목소리만 들리니 개발자들은 다들 그런줄로 착각하는 겁니다. 물론 #1 이나 #2에도 훌륭한 개발자가 있는 경우가 있지만, 그런 사람들은 대부분 조용하거나 알아듣지 못할 말만 늘어놓습니다. 대부분의 경우 이들은 훌륭한 해커는 될 수 있을지 몰라도 훌륭한 제작가는 못 되는 경우가 많습니다.</p>
<p>그래서 결국 격무에 시달리면서 상사의 지시와 사용자의 욕지기를 직접 들어야 하는 개발자는 최후의 선택을 합니다. 탈옥 사용자는 지원하지 않는 것 말입니다. 탈옥을 지원하라며 화내는 사용자들은 애플에게 보내면 됩니다. 제 생각에 이정도로 서드파티를 생각해 주는 플랫폼 벤더는 역사상 처음인 것 같군요. 아 콘솔 게임 플랫폼들이 있지만, 거기서 개발하려면 SDK라이센스하는데만도 최소한 몇만달러가 듭니다. 연 10만원의 ADC 회원권은 거저나 다름없습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/798/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>몇몇 선별된 문서 타입을 표시하기 위해 UIWebView 사용하기</title>
		<link>http://blog.eonil.com/post/769</link>
		<comments>http://blog.eonil.com/post/769#comments</comments>
		<pubDate>Fri, 11 Feb 2011 09:54:13 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=769</guid>
		<description><![CDATA[UIWebView는 HTML뿐 아니라 Excel, Keynote, Numbers, Pages, PDF, Powerpoint, Word 문서를 표시할 수 있습니다. 물론 제약이 있지만 기본적인 것은 대부분 표현 가능합니다. 일반적인 HTML 문서와 같은 방식으로 파일 바이너리를 로드하면 되며, iOS 3.0부터는 RTF, iWork &#8217;09 의 파일 포맷도 지원합니다. 참조: http://developer.apple.com/library/ios/#qa/qa2008/qa1630.html]]></description>
			<content:encoded><![CDATA[<p>UIWebView는 HTML뿐 아니라 Excel, Keynote, Numbers, Pages, PDF, Powerpoint, Word 문서를 표시할 수 있습니다. 물론 제약이 있지만 기본적인 것은 대부분 표현 가능합니다. 일반적인 HTML 문서와 같은 방식으로 파일 바이너리를 로드하면 되며, iOS 3.0부터는 RTF, iWork &#8217;09 의 파일 포맷도 지원합니다.</p>
<p>참조: <a href="http://developer.apple.com/library/ios/#qa/qa2008/qa1630.html">http://developer.apple.com/library/ios/#qa/qa2008/qa1630.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/769/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C를 함수형 스타일로 사용해 게임 로직 구현하기</title>
		<link>http://blog.eonil.com/post/762</link>
		<comments>http://blog.eonil.com/post/762#comments</comments>
		<pubDate>Tue, 25 Jan 2011 09:06:06 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=762</guid>
		<description><![CDATA[C는 함수형 언어가 아니므로 완전히 함수형으로 사용할 수는 없습니다. 하지만 pure-function과 immutability 같은 주요 함수형 스타일의 이점은 포기하기에는 너무 달콤합니다. 게임 로직과 같이 복잡한 프로그램은 함수형 스타일로 작성하는 쪽이 훨씬 더 쉽고 빠릅니다. 하지만 C를 함수형 스타일을 네이티브하게 지원하지 못합니다. 그래서 몇 가지 방법을 생각해 보았습니다. 먼서 게임 로직은 틱이라는 실행 단위로 명확히 구분됩니다. 틱은 [...]]]></description>
			<content:encoded><![CDATA[<p>C는 함수형 언어가 아니므로 완전히 함수형으로 사용할 수는 없습니다. 하지만 pure-function과 immutability 같은 주요 함수형 스타일의 이점은 포기하기에는 너무 달콤합니다.</p>
<p>게임 로직과 같이 복잡한 프로그램은 함수형 스타일로 작성하는 쪽이 훨씬 더 쉽고 빠릅니다. 하지만 C를 함수형 스타일을 네이티브하게 지원하지 못합니다. 그래서 몇 가지 방법을 생각해 보았습니다.</p>
<p>먼서 게임 로직은 틱이라는 실행 단위로 명확히 구분됩니다. 틱은 입력을 받아 현재 게임 상태를 계산하고 종료합니다. 게임은 이 틱이 무한히 수행되어 이뤄집니다. 즉, 틱간에 유지되어야 할 상태는 없습니다. 상태는 유지하는 것이 아니라, 매번 새로 만들어지는 것입니다.</p>
<p>전통적인 명령형 로직에서 필요했던, &#8216;상태&#8217; 자체가 필요가 없어집니다. 작은 상태들을 계산해내는 작은 순수함수들이 조합되어, 결국 큰 전체 상태 하나를 계산해내는 최종 함수로 구성됩니다.</p>
<p>C는 기본적으로 이러한 동작에 잘 맞게 구성되어 있으나, 문제는 카피 부하입니다. 최종적인 전체 상태에 가까워질수록 데이터셋이 커지게 되는데, C에서 리턴한다는 것은 어떤 변수에 할당한다는 것이므로, 최소한 한 번 이상의 카피가 이루어집니다. 이것은 막대한 부하를 불러옵니다. 가능한한 카피를 최소화해야 합니다. 레퍼런싱/디레퍼런싱 부하가 아무리 크더라도 KB단위의 카피 부하에는 미치지 못할 것입니다.</p>
<p>그래서 큰 데이터는 글로벌 영역에 할당할 수 밖에 없습니다. 글로벌 영역은 완전한 정적영역으로, 게임 데이터를 저장하기에 안성맞춤입니다. 큰 데이터는 이러한 메모리 덩어리에 할당하고, 그 포인터를 얻어 사용합니다. 한번 초기화된 데이터는 const로 한정해 변화를 금지합니다.</p>
<p>예를 들면 이렇습니다.</p>
<blockquote><p>
<code></p>
<p>typedef		const struct T		T;</p>
<p>struct T<br />
{<br />
	int	e;<br />
};</p>
<p>struct T PoolOfT[1024];</p>
<p>T*	MakeT()<br />
{<br />
	struct T*	t	=	PoolOfT+12;</p>
<p>	t-&gt;e	=	10;</p>
<p>	return		t;<br />
}</p>
<p>int main (int argc, const char * argv[])<br />
{<br />
	T* t	=	MakeT();</p>
<p>	printf("%d", t-&gt;e);</p>
<p>    return 0;<br />
}</p>
<p></code>
</p></blockquote>
<p>이렇게 하면 덩치 큰 데이터를 카피 오버헤드 없이 다룰 수 있습니다. 글로벌 영역은 정적이므로 해제할 필요도 없습니다. 틱 단위로 필요한 만큼만 쓰고, 틱이 지나고 나면 틱 동안 사용된 수를 무효화시켜버리면 그만입니다.<br />
여기서 한 가지 문제가 되는 것은 글로벌 영역이 고정이라는 것입니다. 한정된 수의 개체만 만들 수 있으며, 이를 초과할 수 없습니다. 또한 개별적인 타입에 대해 각각 풀링 처리를 해주어야 합니다. 큰 개체의 부하를 해결할 수 있지만, 필요한 것이 너무 많습니다. 이것은 일종의 최적화입니다. 하지만 대부분의 타입은 덩치가 상당히 크고, 타입이 많이 필요할 수 밖에 없는 만큼, 간편하게 큰 개체 타입을 만들 수 있도록 해야 합니다.</p>
<p>결국 힙이 다시 나옵니다. 힙에 동적 할당합니다. 그리고 NSAutoreleasePool과 같은 컨셉으로 이들의 포인터를 모읍니다. 데이터는 한 틱 안에서만 유효하고, 틱이 종료되면 모두 해제됩니다. 다음 틱에서도 데이터가 살아남으려면 반드시 복사되어야 합니다. 카피 오버헤드는 한 틱 안에서만의 데이터 전달시에만 고려하며, 다른 틱으로의 데이터 전달은 고려하지 않습니다. 힙에 할당된 데이터는, 다른 틱으로 전달될 때 반드시 카피되어야 합니다. 그런데 이러한 어프로치는 문제가 많습니다. 사람이란, 꼭 카피해야 한다는 것을 잊기 마련이니까요. 함수형 스타일을 도입하려 한 취지와 맞지 않습니다. 하지만 힙에 있는 데이터는 어떤 종류든지 관리가 필요합니다.</p>
<p>그래서 힙은 포기할 수 밖에 없습니다. 힙을 사용하면 간단하고 디버깅이 쉬운 코드를 만들 수 없습니다. 그래서 기본적으로 카피, 큰 데이터는 글로벌 영역에서 풀링한다는 두 가지 컨셉으로만 작성해야 합니다. 중간은 없으며, 카피 부하를 감당하든지, 글로벌 영역의 구조를 작성하든지 둘 중의 하나일 것입니다. 약간만 늘어난 부하로 매우 쉬운 구조를 가진 프로그램을 만들 수 있죠.</p>
<h1>룰 외 부분</h1>
<p>지금까지 설명한 것은 어디까지나 게임 룰 로직입니다. 게임 룰 로직만이라면 위의 제약으로도 쓸만한 코드를 작성하는 것이 가능합니다. 렌더링, 네크워킹, 입력 등의 다른 부분은 따로 작성해야 합니다. 이들은 크로스플랫폼이 될 수 없는 부분이므로 각 플랫폼마다 개별적으로 작성하는 것이 더 적합하기도 하구요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/762/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photo Booth에서 플래시 없이 사진 찍기</title>
		<link>http://blog.eonil.com/post/738</link>
		<comments>http://blog.eonil.com/post/738#comments</comments>
		<pubDate>Sun, 02 Jan 2011 23:27:27 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=738</guid>
		<description><![CDATA[맥용 셀카 앱인 Photo Booth는 사진을 찍을 때 자동으로 화면을 밝게 만들어 플래시로 동작하게 합니다. 이를 끄려면 붉은색 찍기 버튼을 클릭할 때 Shift 키를 누르고 있으면 됩니다.]]></description>
			<content:encoded><![CDATA[<p>맥용 셀카 앱인 Photo Booth는 사진을 찍을 때 자동으로 화면을 밝게 만들어 플래시로 동작하게 합니다. 이를 끄려면 붉은색 찍기 버튼을 클릭할 때 Shift 키를 누르고 있으면 됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/738/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>화면 픽셀과 실수 공간 좌표계</title>
		<link>http://blog.eonil.com/post/694</link>
		<comments>http://blog.eonil.com/post/694#comments</comments>
		<pubDate>Tue, 14 Dec 2010 16:42:44 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=694</guid>
		<description><![CDATA[UI 그래픽을 다룰 때, 화면 픽셀을 제대로 다루는 것은 생각외로 어렵습니다. 왜냐면 화면 픽셀이 너무 크기 때문입니다. 픽셀이 너무 커서, 픽셀 사이에 걸쳐진 점을 보간해도 흐릿한 점으로만 보이기 때문입니다. 그래서 보통 그래픽을 다룰 때는 픽셀에 딱 맞추는 것을 중요하게 여겨 이를 픽셀 그리드에 정렬한다라고 합니다. 그래서 보통 기본적으로 좌표나, 사이즈를 정수 단위로 줍니다. 실수로 계산하고, [...]]]></description>
			<content:encoded><![CDATA[<p>UI 그래픽을 다룰 때, 화면 픽셀을 제대로 다루는 것은 생각외로 어렵습니다.<br />
왜냐면 화면 픽셀이 너무 크기 때문입니다. 픽셀이 너무 커서, 픽셀 사이에 걸쳐진 점을 보간해도 흐릿한 점으로만 보이기 때문입니다.</p>
<p>그래서 보통 그래픽을 다룰 때는 픽셀에 딱 맞추는 것을 중요하게 여겨 이를 <strong>픽셀 그리드에 정렬한다</strong>라고 합니다. 그래서 보통 기본적으로 좌표나, 사이즈를 정수 단위로 줍니다. 실수로 계산하고, 또 결과가 실수로 나오더라도, 정수로 보정합니다.</p>
<p>그런데 여기엔 다소 어려움이 있습니다. 바로 <strong>중앙 정렬</strong>입니다.<br />
예를 들어 가로 100px의 화면에 중앙에 5px 짜리 오브젝트를 그린다고 합시다. 실수 좌표계에서는 이것이 간단합니다. 그냥 중간인 2.5px부근에 맞춰서 중앙 정렬시키면 됩니다.</p>
<p>하지만, 결국 모든 그래픽이 출력되는 곳은 화면이므로, 화면 픽셀에 의해 제한을 받을 수 밖에 없습니다. 하지만 화면 픽셀은 자비가 없습니다. 2.5 px 같은 곳에는 칼라를 출력할 수 없습니다. 2아니면 3입니다. 양쪽으로 2.5px씩 나눠야 하는데, 픽셀을 더 쪼갤 수가 없으니 환장할 노릇입니다.<br />
그래서 보통 이런 때는,</p>
<ul>
<li>랜덤으로 한쪽으로 치우치든지,</li>
<li>보간되어 두 픽셀 사이에 걸쳐진 흐릿한 점들을 나타나게 할 것입니다.</li>
</ul>
<p>전자는 결정적이지 않은 결과를 얻으므로 명백히 좋지 않습니다. 후자가 더 낫지만, 사실 결과물을 보면 만족할 수 없습니다. 그래서 사용하는 것은 명시적으로 한쪽으로 치우치게 하는 것입니다. 뭔가 찝찝하지만 그래픽은 선명하게 나오기에 만족스럽습니다.</p>
<p>그런데 더 큰 문제가 발생했습니다. 만약 그 5px짜리 오브젝트 안에 4px짜리 오브젝트를 하나 더 그리면 어떻게 될까요? 5px짜리 오브젝트의 중앙은 어디일까요. 설상가상으로 4px짜리 오브젝트를 그려야 할 때에는 5px짜리 오브젝트의 위치는 알 수 없습니다.</p>
<p>5px짜리 오브젝트가 픽셀에 정렬되어 있지 않다면, 0.14px쯤에 출력될 수도 있고, 사실상 어떻게 출력될지 알 수가 없으니 픽셀에 맞추는 것 자체가 불가능합니다. 그래서 픽셀에 정렬되어 있다고 가정하고 처리를 하는데, 그래도 결국 한쪽으로 치우치게 하는 수 밖에 없습니다. 이런 식으로 계속 한쪽으로 치우치게 하다 보면 몇번만 중첩되어도 한쪽으로 쏠리는 게 느껴질 겁니다. 안쪽 단계를 그리는 시점에서는 바깥쪽 단계의 상태를 알 수 없기 때문에 매 단계마다 다른 방향으로 치우치게 하는 것도 불가능합니다.</p>
<p>뭣하러 그 안에다 그리는가? 그냥 5px짜리를 그릴 때 같이 그리면 되지 않는가? 하는 의문이 생깁니다. 네, 그러면 됩니다. 그러면 진짜 간단하고 쉽게 해결 할 수 있습니다. 모든 요소가 하나의 좌표계 안에 있는 것이죠. 하지만 문제는 대부분의 UI 프레임워크가 이런 식으로 구성되어 있다는 것입니다. 왜냐면 UI 요소를 묶어서 하나의 덩어리로 만들어 재사용하는데, 거기에는 또 이만한 방법이 없거든요. 기존 프레임워크를 반드시 사용해야만 하는데, 이를 고칠 수는 없습니다.</p>
<p>그래서 제가 생각해낸 방법은 단순히 모든 요소의 크기를 2의 배수, 즉 짝수로 고정시키는 방법입니다. 칼같이 얇은 1px짜리 요소를 끼워넣거나 하는 트릭은 쓸 수 없게 되는 대신, 어디에서 센터를 잡아도 픽셀 중간에 걸리는 일이 없게 됩니다. 그리고 뭔가 기준점을 잡거나 할 때도 항상 짝수로만 잡습니다. 모든 레이아웃을 짝수로만 합니다. 하지만 모든 곳에 이를 적용할 수는 없습니다. 특히 고정된 공간을 나눠야 하는 때에는 이 방법을 사용할 수 없습니다. 100px 길이의 테이블을 9개로 나눈다고 하면 11px로밖에 할 수 없습니다. (하나는 12px이므로 제대로 나눴다고도 할 수 없습니다.) 이런 상황을 완전히 회피할 수 있을 때만 사용 가능한 방법입니다. 대신 이 방법은 굉장히 잘 작동합니다.</p>
<p>아이폰4의 레티나 디스플레이에서는 한 번 더 생각해야 합니다. 기본적인 좌표계가 0.5배로 확대되어 있기에, 레티나 디스플레이 전용 그래픽을 제작한다면, 이러한 정렬을 해 줄 필요가 없습니다. 이러한 방식을 응용해서 기본 좌표계의 해상도를 줄여두는 것도 한 방법이 될 수 있겠군요. 하지만 그래픽 아티스트와의 커뮤니케이션 문제가 심각해질 수 있으니 권장하지는 않습니다.</p>
<p>하지만 다른 문제가 있습니다. 문제는 비트맵 소스를 제작할 때입니다. 기본적으로 반절 해상도인 구버전 기기들에 대한 지원을 생각하지 않을 수 없기에, 모든 그래픽은 기본적으로 짝수로 만들어집니다. 이것을 위에서 말한 테크닉을 사용하려면 모든 요소의 크기를 4배수로 고정해야 합니다. 짝수까지는 군말없이 맞춰주던 그래픽 아티스트들도 4배수에서는 불만이 나오더군요. 쉽게 하려면 저해상도용 소스를 짝수로 만든 다음 이를 2배로 확대해 디테일을 늘려주는 방식으로 작업하면 됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/694/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objective-C의 private메서드와 이름짓기 관습 (naming convention)</title>
		<link>http://blog.eonil.com/post/687</link>
		<comments>http://blog.eonil.com/post/687#comments</comments>
		<pubDate>Mon, 13 Dec 2010 13:37:16 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=687</guid>
		<description><![CDATA[이번에는 Objective-C의 이름짓기 관습에 대해서 알아보겠습니다. C의 수퍼셋으로 C의 특성을 그대로 물려받은 결과, Objective-C는 private 메서드도 없고, 이름 보호 기능도 없습니다. private 메서드는 그냥 단순히 문서화하지 않은 (즉 헤더파일에 기록되지 않은) 메서드일 뿐입니다. 그래서 서브클래스에서도 이를 아무 제한 없이 호출할 수 있으며, 심지어 오버라이드 할 수도 있습니다. 그러면 이런 시나리오를 생각해 볼 수 있습니다. 수퍼클래스에서 [...]]]></description>
			<content:encoded><![CDATA[<p>이번에는 Objective-C의 이름짓기 관습에 대해서 알아보겠습니다.</p>
<p>C의 수퍼셋으로 C의 특성을 그대로 물려받은 결과, Objective-C는 private 메서드도 없고, 이름 보호 기능도 없습니다. private 메서드는 그냥 단순히 문서화하지 않은 (즉 헤더파일에 기록되지 않은) 메서드일 뿐입니다.<br />
그래서 서브클래스에서도 이를 아무 제한 없이 호출할 수 있으며, 심지어 오버라이드 할 수도 있습니다. 그러면 이런 시나리오를 생각해 볼 수 있습니다. 수퍼클래스에서 보이지 않는 (즉, private인) 메서드가 하나 있는데, 서브클래스에서 우연히 같은 이름의 메서드를 작성한 경우입니다. 메서드가 조용히 오버라이드 되므로, 논리가 깨지고 버그로 이어집니다. 다이나믹 디스패치를 중시한 디자인이므로, 이해는 할 수 있지만, 사실 잠재적인 불안요소입니다. 이러한 선언되지 않은 이름의 충돌에 대해서 경고하는 자동화된 메카니즘이 있으면 좋겠지만, 아쉽게도 그런 것은 마련되어 있지 않습니다. 아무런 경고도 에러도 없습니다.</p>
<p>대신, 이를 방지하는 수동 메카니즘은 있는데, 그것은 이름짓기 관습입니다. 그래서 Objective-C의 이름짓기는 관습이지만 반드시 알아야만 하는, 일종의 규칙입니다. 알지 못하면 안정성을 보장 할 수 없게 됩니다.</p>
<h1>레퍼런스</h1>
<p>먼저 <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html%23//apple_ref/doc/uid/20001281-BBCHBFAH">레퍼런스</a>를 보세요. 이게 정답입니다.</p>
<p>레퍼런스는 일반적인 케이스에 관해서 언급하고 있는데요, 쉽게 지나칠만한 내용 하나를 따로 언급하자면,</p>
<blockquote><p>하나의 밑줄 &#8216;_&#8217;로 된 프리픽스는 애플이 Cocoa의 private 메서드용으로 예약</p></blockquote>
<p>했다는 겁니다. 그래서 메서드 이름을 이것으로 프리픽스하면 안됩니다. 메서드 이름 중복의 원인이 될 수 있습니다. 레퍼런스에서는 <code>BF_</code> 같은 추가적인 이름을 더 프리픽스하는 것을 제시합니다만, 특정 방식을 강조하지는 않았습니다. 뭐든지 단일 밑줄만 아니면 괜찮습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/687/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>구글 TV와 애플 TV와 미디어 컨텐츠</title>
		<link>http://blog.eonil.com/post/663</link>
		<comments>http://blog.eonil.com/post/663#comments</comments>
		<pubDate>Thu, 09 Dec 2010 02:22:44 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Think]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=663</guid>
		<description><![CDATA[소니의 구글 TV가 잘 안나간다는 기사를 접했습니다. 구글 TV연합에 소니같은 제조업계 거물들만 있고, 미디어 업계의 거물은 전혀 없다는 것을 보고는 이렇게 되리라 예측은 했지만, 정말 이렇게 되니 또 새롭네요. 구글 vs 미디어 컨텐츠 구글은 처음부터 미디어 컨텐츠 업계와 사이가 안좋았습니다. 처음에는 뉴스사, 그다음엔 출판사, 그리고 지금은 방송국이죠. 잘은 모르지만 영화사와도 친하지는 않을겁니다. 그 이유는 단순합니다. [...]]]></description>
			<content:encoded><![CDATA[<p>소니의 구글 TV가 잘 안나간다는 기사를 접했습니다. 구글 TV연합에 소니같은 제조업계 거물들만 있고, 미디어 업계의 거물은 전혀 없다는 것을 보고는 이렇게 되리라 예측은 했지만, 정말 이렇게 되니 또 새롭네요.</p>
<p>구글 vs 미디어 컨텐츠</p>
<p>구글은 처음부터 미디어 컨텐츠 업계와 사이가 안좋았습니다. 처음에는 뉴스사, 그다음엔 출판사, 그리고 지금은 방송국이죠. 잘은 모르지만 영화사와도 친하지는 않을겁니다.</p>
<p>그 이유는 단순합니다. 구글의 수장이 미디어 업계의 신뢰를 얻지 못했기 때문입니다.</p>
<p>구글은 전형적이다 못해 너무할 정도로 강력한 기술 중심 기업입니다. 현존하는 시스템의 문제를 파악하고 이를 개선하는 것으로 부가가치를 창출하죠. 구글이 기반으로 삼고 있는 특화된 분야는 검색인데, 검색을 더욱 잘 하려면 검색할 정보 소스에 대해 더욱 가까이 접근할 필요가 있습니다. 그래서 구글은 항상 모든 정보를 <strong>대가 없이</strong> 공유해야 한다고 주장합니다.</p>
<p>그런데 미디어 업계의 이윤은 구글이 안다면(!) 정말 깜짝 놀랄 정도로 저작권에 기반합니다. 저작권이 없다면 이 업계는 근본부터 흔들립니다. 저작권이 없다면 기존에 나온 책, 음악, 영상을 그냥 복사해서 팔아도 아무도 처벌받지 않을 거고, 그럼 작품만 만들어서는 생활을 유지 할 수 없게 됩니다. 전업 작가가 없어지는 거죠. 아무리 글 쓰는 것을 좋아한다 해도, 노래하는 것이 좋다 해도, 시간을 많이 투자할 수 없다면 좋은 글을 쓰고 좋은 음악을 만들기는 어렵습니다. 이렇게 전업 작가가 없어지면 좋은 작품이 나올 수가 없고, 그러면 이들을 유통하는 출판사, 음반사, 방송국도 같이 망하는 겁니다. 컨텐츠 업계가 무허가 복제에 그렇게 민감한 것은, 그것이 저작권이 미디어 업계 전체를 떠받치고 있기 때문입니다.</p>
<p>저작권이 무시되어서 업계 전체가 폭삭 망해버린 사례는 어렵지 않게 찾을 수 있습니다. 바로 여기 한국을 보면 됩니다. 음반의 저작권이 무시되어 음반 판매가 부진하자, 음반만으로 먹고살던 사람들이 모두 쫒겨나고, 음반은 홍보수단으로 전락했습니다. 한국산 소설, 만화 등을 보기 힘든 것도 마찬가지 이유입니다. 게임업게도 고사 직전에서 온라인 게임으로 겨우 탈출했습니다. (온라인 게임은 복제가 거의 불가능하거든요) 한국에서 직접 판매에 기반한 독립 소프트웨어로 돈을 벌 수 없다는 것은 이제 오래된 이야기입니다.</p>
<p>그런데 구글은 항상 이 저작권을 무시해 왔습니다. 왜냐면 구글에게 이것은 그냥 정보의 일종일 뿐이기 때문입니다. 구글에게 정보는 그냥 자연상에 존재하는 것으로서 이를 정복해야 할 대상으로만 생각합니다. 이 정보들이 결국 누군가의 노력으로 만들어졌다는 생각은 하지 못한 것이죠. 왜냐면 지금까지는 웹이라는 공개된 정보만을 다루어 왔기 때문입니다. 웹에 올라온 정보들은 공개를 목적으로 올리는 것이기 때문에 아무 반발이 없었고, 그 덕분에 구글은 이 자원들을 마음대로 사용해왔습니다.</p>
<p>그런데 저작물은 이야기가 다릅니다. 그 중에서도 작가라 불리는 고수들이 만들어낸 것을 작품이라 하는데, 이것을 만드는 데는 상상을 초월하는 노력이 들어갑니다. 경제학 용어로는 비용이라고 하죠. 너무나 힘이 들어서 대부분의 경우 보장된 이윤이 없으면 이런것을 하려는 사람이 없습니다. 지금까지는 저작권이 바로 그 보장된 이윤이었습니다. 내 작품을 보려면 요금을 내라는 단순한 시스템 말이죠. 그게 편당 천원의 요금이든지, 스폰서가 내는 광고비든지 말이죠. 작품이 꼬져서 보려는 사람이 없다며 할 말이 없지만, 보고도 값을 치르지 않는다면 문제가 있죠.</p>
<p>저작권이라는 것은 별 것이 아닙니다. 저작권은 작가의 권리입니다. <strong>작품을 사용할 때는 작가의 허가를 받는 것.</strong> 이것이 저작권의 전부입니다. 라이센스죠. 그런데 단순히 어렵고 귀챃다는 이유로 이를 무시합니다. 구글은 뉴스기사를 <strong>허가 없이</strong> 재편집해서 신문사의 공적이 되었습니다. 출판물을 <strong>허가 없이</strong> 전자화해서 출판계의 공적이 되었습니다. 유튜브에 <strong>허가받지 않은</strong> 영상물 배포를 묵인해 방송국과 영화사의 공적이 되었습니다.</p>
<p>물론 뒤늦게 프로젝트를 취소하고, 조치를 취하긴 했지만, 그것은 중요한 게 아닙니다. 구글은 미디어 업계를 이해하지 못하고 있다는 것을 강력하게 어필한 것이죠. 미디어 업계를 이해하지 못하는 구글이 미디어 업계의 이윤을 보전해 줄 수 있을리가 없다고 생각하게 된 겁니다. 그렇지 않아도 인터넷을 통한 무허가 복제로 골치를 앓고 있는 상황인데, 구글은 틈만 나면 자기들의 이윤을 훔쳐가려는 무리로 보인 것입니다.</p>
<p>구글이 순진해서, 기술밖에 몰라서 그렇다고 이야기할 수는 없습니다. 왜냐면 그들도 저작권과 유사한 특허권으로 먹고살기 때문입니다. 페이지랭크 알고리즘이 특허로 보호되지 않았다면 지금의 구글도 있을 수 없습니다. 페이지와 브린, 슈미츠가 자문을 구할 만한 지적재산권 관련 변호사가 구글에 없을 리 없는데 저작권 침해라는 것을 아예 생각하지 못했거나 의도적으로 침해했다고 볼 수 밖에 없는 상황이 된 거죠. 또한 최근에 MPEG의 비디오 압축 알고리즘의 특허를 다수 침범했다고 의심받고 있는 WebM을 발표하면서, 특허에 관한 의문을 제대로 해결하지 않고 넘어가는 자세를 보면, 미디어 업계로서는 도저히 신뢰를 보내줄 수 없게 됩니다.</p>
<p>애플 vs 미디어 컨텐츠</p>
<p>애플, 아니 잡스는 미디어 업계를 잘 이해합니다. 이들의 환심을 얻기 위해서는 이들을 존중해주고, 사전에 허가를 받기만 하면 된다는 것을 잘 압니다. 그래서 잡스는 컨텐츠 사업을 할 때 반드시 사전 허가를 받습니다. 허가가 나지 않으면 시작하지도 않습니다. 아이튠즈 스토어를 열 때 먼저 음반사와 협상했습니다. 그 후에 TV쇼와 영화를 추가할 때도 항상 먼저 방송국과 영화사와 협상했습니다. 북스토어를 열기 전에도 출판사와 협상했습니다. 남의 재산을 갖다 쓰기 전에 먼저 협상해야 한다는 것은 극히 기본적인 것입니다. 여기까지는 평범합니다. 잡스가 빛나는 것은 유통업자뿐만이 아닌, 작가들까지 포섭했다는 것입니다. 유통업자들의 이윤은 물론, 작가들의 이윤도 잊지 않고 챙겨주겟다는 자세입니다. 음악가, 영화감독들과의 친분도 한 몫 합니다. </p>
<p>하지만 무엇보다도 중요한 것은 잡스가 이들과 동족이라는 것입니다. 잡스는 픽사를 설립해 직접 미디어 사업을 해 보았고, 성공했으며, 지금은 디즈니의 대주주입니다. 즉, 미디어 업계의 이윤이 곧 잡스의 이윤입니다.</p>
<p>저작물도 정보로 생각해 마음껏 검색할 수 있게 해야 이윤이 발생하는 구글과는 대조적입니다. 게다가 구글은 아무말없이 저작물을 갖다 쓰다가 걸린 적이 한두번이 아닙니다. 페이지와 브린, 슈미츠는 골수 공학도로, 미디어 업계와는 전혀 친분이 없습니다.</p>
<p>앞으로</p>
<p>앞으로도 구글이 미디어 업계의 지원을 받기는 쉽지 않을 것입니다. 구글 TV의 앞이 어두운 것은 그 때문이지요. 구글 TV는 스마트 TV라고는 하지만 기본적으로는 TV입니다. 컨텐츠가 있어야 해요. 그리고 보통 TV라면 미디어 컨텐츠를 기대합니다.</p>
<p>구글이 하드웨어 제조사와 연합한 것은 MS모델을 따르기 때문입니다. 애플은 하드웨어 업체이기 때문에 하드웨어 업체의 지원을 기대할 수 없는 상황이죠. </p>
<p>어찌보면 미국 언론이 애플과 아이패드에 열광하는 것은 필요 이상일지도 모릅니다. 대부분의 언론사가 구글을 기사 및 광고 도둑 정도로 생각하기 때문입니다. 국내에서 갤럭시 S가 필요 이상으로 호평받는 것과 같은 이치겠지요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/663/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OCUnit</title>
		<link>http://blog.eonil.com/post/651</link>
		<comments>http://blog.eonil.com/post/651#comments</comments>
		<pubDate>Wed, 08 Dec 2010 11:15:05 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=651</guid>
		<description><![CDATA[오늘 OCUnit을 써봤습니다. 다 적절한데, 한가지 문제가 있더군요. 테스트 코드를 디버깅할 수 없다는 겁니다. 테스트는 쉘에서 시행되어 결과만 출력해줍니다. 저같이 실수를 많이 하는 사람은 한 번에 버그 없는 기능을 작성하기는 매우 힘들고, 기능을 작성하는 도중에 테스트와 디버깅을 많이 하게 되는데, 본 앱 코드에서 이런 테스트를 하면 상당히 많은 시간을 낭비하게 됩니다. 하지만 테스트 스위트는 오로지 [...]]]></description>
			<content:encoded><![CDATA[<p>오늘 OCUnit을 써봤습니다. 다 적절한데, 한가지 문제가 있더군요. 테스트 코드를 디버깅할 수 없다는 겁니다. 테스트는 쉘에서 시행되어 결과만 출력해줍니다. 저같이 실수를 많이 하는 사람은 한 번에 버그 없는 기능을 작성하기는 매우 힘들고, 기능을 작성하는 도중에 테스트와 디버깅을 많이 하게 되는데, 본 앱 코드에서 이런 테스트를 하면 상당히 많은 시간을 낭비하게 됩니다. 하지만 테스트 스위트는 오로지 테스트만 수행하는 코드이므로, 이러한 테스트와 디버깅을 최적화된 형태로 수행할 수 있습니다.</p>
<h1>테스트 디버깅</h1>
<p>하지만 테스트 코드가 디버깅이 되지 않는 것을 보니 좀 그렇더군요. 기존에 나온 솔루션은 두가지 옵션이 있었습니다.</p>
<ul>
<li>구글 코드에 공개된 google-toolbox-for-mac을 사용하는 것과</li>
<li>otool (Sen Test)을 커스텀으로 실행해 디버깅을 강제 수행하는 것</li>
</ul>
<p>입니다.</p>
<p>먼저 구글 툴박스는 쉽게 선택할 수가 없었습니다. 여기에는 다수의 툴이 포함되어 있는데, 이 중에는 Xcode의 플러그인도 포함됩니다. 왜냐면 Xcode 3.x는 플러그인 구조가 공개되어 있지 않기 때문입니다. 그렇다면 이 툴은 해킹으로 작성된 툴입니다. 즉, Xcode의 변화에 민감할 수 밖에 없고, 어느날 SDK를 업데이트한 순간 작동되지 않을 수도 있게 됩니다. 그리고 애플은 하위호환에 크게 구애받지 않는 공격적인 업데이트를 하는 회사죠. SDK 업데이트가 공개된 날부터 이전 SDK로 컴파일한 바이너리는 공식적으로 앱스토어에서 거부됩니다. 그러니 이건 생각보다 심각한 문제죠. 그러데 툴박스 사이트에는 &#8220;Successful installation on Snow Leopard on /Developer/Library/Xcode/Plug-ins&#8221; 같은 메시지들이 다수 올라와 있습니다. 인스톨 성공을 코멘트할 정도로 인스톨이 불안정하다는 뜻일 겁니다.</p>
<p>결국 otool의 커스텀 수행을 사용하기로 했습니다. 그리고 이 구글 툴박스 또한 결국 SenTest를 사용한다는 메시지를 보고는 웹을 뒤적여서 몇 가지 방법을 찾아냈죠.</p>
<p>그런데 작동이 안되는 겁니다. 분명 뭔가 세팅을 잘못했거니 하고 생각은 했지만, 이걸 제대로 세팅하려면 시간이 너무 많이 걸릴 것 같더군요. 그래서 제 3의 선택, OCUnit을 직접 실행시키기를 선택했습니다.</p>
<h1>OCUnit 테스트 직접 실행하기</h1>
<p>먼저 애플리케이션 타겟을 하나 만듭니다.<br />
이 타겟에 테스트에 필요한 소스 .m 파일들을 모두 추가하고, SenTest 프레임워크를 추가해 줍니다. 이 프레임워크는 <code>/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk/Developer/Library/Frameworks/SenTestingKit.framework</code>에 있습니다. SDK마다 경로가 달라지겠죠. 일단 현재 SDK에 맞는 프레임워크를 추가하고 프로젝트 엔트리의 속성에서 Path Type을 Relative to Current SDK로 바꿔줍니다. 그리고 Choose&#8230; 버튼을 사용해 다시 로드해주면 상대 경로로 지정되어 SDK가 바뀌더라도 문제 없게 됩니다.</p>
<p>그리고 이 타겟에 새로운 Main.m을 만들어 추가한 뒤, 메인함수를 작성해 줍니다.</p>
<blockquote><pre><code>#import	

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

	SenTestSuite	*suite	=	[SenTestSuite defaultTestSuite];
	[suite run];

    [pool release];
    return 0;
}</code></pre>
</blockquote>
<p>저 두 줄을 쓰면 테스트 스위트 전체가 수행됩니다.</p>
<h1>TDD (Test Driven Development)</h1>
<p>테스트 주도 개발이란 단어를 접했을 당시에는 그런게 있나보다 정도로만 봤는데, 앱 전체에서 버그를 재현하는 오버헤드 없이 바로 버그 수정을 할 수 있게 된다는 게 굉장히 빠른 개발을 가능하도록 해 주더군요. 또한, 버그 발생시 버그의 정체를 알아내기 위해 이런저런 테스트 코드를 작성했다가 지우기를 반복하는데, 그러한 테스트들을 하나둘씩 쌓아서 프로그램의 품질향상에 기여한다는 컨셉도 훌륭합니다. 한때는 테스트 코드 작성이 중복이며, 시간만 잡아먹는 일이 아닐까 하고 걱정했는데, 테스트 작성에 들이는 시간은 모두 코드 품질 향상으로 이어지고, 또한, 그 덕분에 절약하는 시간을 따져보면 테스트 드라이븐을 꼭 해야 한다고 생각하게 되었습니다. 무엇보다도 자신이 만든 코드에 대해 테스트를 만든 양 만큼의 확신을 가질 수 있게 된다는 것이 가장 큰 이점입니다!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/651/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>로우 레벨 언어와 하이 레벨 언어</title>
		<link>http://blog.eonil.com/post/642</link>
		<comments>http://blog.eonil.com/post/642#comments</comments>
		<pubDate>Tue, 07 Dec 2010 17:12:30 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=642</guid>
		<description><![CDATA[프로그래머라면 로우 레벨 언어와 하이 레벨 언어의 구분이 있고, 이 구분이 명확한 것은 아니라는 것은 누구나 다 알 것입니다. 저도 여기까지만 알았었죠. 하지만 최근 들어 크게 느껴지는 게 있습니다. 여러 가지 언어를 같이 써야 한다는 것이죠. 로우레벨 언어의 특징은 고성능과 명료함일 것입니다. 그래서 단단한 하부 시스템을 만드는 데 좋죠. 하지만 복잡한 로직을 만들기는 어렵고, 시간이 [...]]]></description>
			<content:encoded><![CDATA[<p>프로그래머라면 로우 레벨 언어와 하이 레벨 언어의 구분이 있고, 이 구분이 명확한 것은 아니라는 것은 누구나 다 알 것입니다. 저도 여기까지만 알았었죠. 하지만 최근 들어 크게 느껴지는 게 있습니다. 여러 가지 언어를 같이 써야 한다는 것이죠.</p>
<p>로우레벨 언어의 특징은 고성능과 명료함일 것입니다. 그래서 단단한 하부 시스템을 만드는 데 좋죠. 하지만 복잡한 로직을 만들기는 어렵고, 시간이 오래 걸리게 됩니다. 로직이 조금만 복잡해져도 코드가 매우 번잡해지니까요. 그래서 하이레벨 언어가 등장합니다.</p>
<p>하이레벨 언어는 쉽고 빠르게 로직을 작성하기 위해 고성능과 명료함을 포기하는 대신, 유연함과 표현력을 얻습니다. 로직을 기술하기 위한 것이죠. 그리고 이러한 특성을 얻기 위해 추상화를 사용합니다. 세부 처리 사항을 숨기고, 적은 표현으로 많은 일을 수행할 수 있게 합니다. 이러한 것에 집중한 결과 세부적인 특성도 생겨납니다. 짧고 간결한 코드, 고도로 압축된 표현 문법 등이죠.</p>
<p>하나의 언어로 모든 것을 만족시킬 수는 없습니다. C++은 그러한 사례의 대표적인 예입니다. 빠르고, 표현력이 좋지만, 암묵적인 표현이 너무 많아 명료함이 부족합니다. 그래서 코드를 쓰는 것도 읽는 것도 매우 어렵습니다. C++의 <code>=</code> 연산자가 수동 메모리 관리를 추상화시킬 수 있지만, 대신 특정 클래스에서 <code>=</code>는 할당 연산자가 아닐 가능성이 생기고, 결국 안전하게 연산자를 쓰기 위해서는 해당 클래스에서 연산자가 어떤 역할을 하는지 확인해야 합니다. Objective-C는 명료한 대신 표현력이 부족합니다. 코드를 읽고 쓰는 것은 쉽지만, 적은 코드로 많은 표현을 할 수는 없습니다. 하지만 <code>=</code> 연산자는 항상 할당이며, <code>=</code> 연산자를 안전하게 쓰기 위해 클래스 문서를 뒤적일 필요는 없습니다.</p>
<p>해법은 계층화입니다. 프로그램을 하부 시스템과 상부 응용로직으로 나눠, 하부는 로우레벨 언어로 구축하고, 상부는 하이레벨 언어로 구현하는 것입니다. 하나의 언어로 모든 것을 해결하는 대신, 각 분야에 적합한 언어를 골라서 사용하면 됩니다. 필요에 따라 한 계층이 생략될 수도 있을 것입니다. 예를 들어 단단한 고성능 하부가 필요 없다면 하이레벨 언어로만 만들면 됩니다. 복잡한 응용로직이 필요 없다면 로우레벨 언어로만 작성합니다.</p>
<p>이건 당연한 겁니다. 하지만 이 사실을 깨닫는 데 너무 오래 걸렸네요. 이러한 분류는 상대적인 거라 어느 언어가 어느 계층이다라는 것은 없겠지만, 프로그램이 커지면 계층을 나눠야 하는 것은 명백합니다. 그리고 다른 계층에서는 다른 언어를 써야 한다는 것도요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/642/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GLES 초기화하기</title>
		<link>http://blog.eonil.com/post/412</link>
		<comments>http://blog.eonil.com/post/412#comments</comments>
		<pubDate>Sat, 04 Dec 2010 12:01:39 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/GL]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=412</guid>
		<description><![CDATA[GLES를 초기화하는 방법은 플랫폼마다 조금씩 다릅니다. 아이폰에서 초기화하는 방법을 알아봅니다. 드로잉 영역으로 사용할 UIView를 만듭니다. GL레이어를 얻습니다. 패러미터를 주어 GL레이어를 초기화합니다. GL컨텍스트를 만들고 설정합니다. 버퍼들을 만들고 바인딩합니다. 뷰포트를 설정합니다. 다음에 보여지는 코드들은 이미지네이션사의 PowerVR SDK에서 발췌한 것들입니다. 뷰 만들기 GL의 그래픽 위에 다른 뷰가 있으면 OS가 별도로 이를 처리해야 하므로 성능저하가 발생합니다. 애플의 가이드 문서는 [...]]]></description>
			<content:encoded><![CDATA[<p>GLES를 초기화하는 방법은 플랫폼마다 조금씩 다릅니다. 아이폰에서 초기화하는 방법을 알아봅니다.</p>
<ol>
<li>드로잉 영역으로 사용할 <code>UIView</code>를 만듭니다.</li>
<li>GL레이어를 얻습니다.</li>
<li>패러미터를 주어 GL레이어를 초기화합니다.</li>
<li>GL컨텍스트를 만들고 설정합니다.</li>
<li>버퍼들을 만들고 바인딩합니다.</li>
<li>뷰포트를 설정합니다.</li>
</ol>
<p>다음에 보여지는 코드들은 이미지네이션사의 PowerVR SDK에서 발췌한 것들입니다.</p>
<h1>뷰 만들기</h1>
<p>GL의 그래픽 위에 다른 뷰가 있으면 OS가 별도로 이를 처리해야 하므로 성능저하가 발생합니다. 애플의 가이드 문서는 절대로 GL뷰 위에 다른 뷰를 올리지 말라고 적고 있습니다.<br />
이 때, 이 뷰는 <code>layerClass</code>라는 정적 메서드를 구현해야 하며, 이 메서드는 <code>[CAEAGLLayer class]</code>를 리턴해야 합니다. 그래야 뷰를 만들때 내부 하부 레이어가 GL레이어가 되기 때문입니다.</p>
<blockquote><pre><code>+ (Class) layerClass
{
    return [CAEAGLLayer class];
}</code></pre>
</blockquote>
<h1>레이어 얻기</h1>
<p>GL레이어를 얻습니다. 위에서 설명한 방법대로 뷰를 만들면 해당 뷰의 레이어가 GL 레이어가 됩니다. 이를 사용하면 됩니다.</p>
<blockquote><pre><code>CAEAGLLayer* eaglLayer = (CAEAGLLayer*)[self layer];</code></pre>
</blockquote>
<p>또한, GL에 패러미터를 넘겨 초기화해야 합니다. 이는 XNA에서의 <code>PresentationParameter</code>와 같습니다.</p>
<blockquote><pre><code>[eaglLayer setDrawableProperties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
    kEAGLDrawablePropertyRetainedBacking,
    kEAGLColorFormatRGBA8,
    kEAGLDrawablePropertyColorFormat,
    nil]];</code></pre>
</blockquote>
<p>3. GL 컨텍스트를 얻고 현재 컨텍스트로 설정합니다.</p>
<blockquote><pre><code>m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
[EAGLContext setCurrentContext:m_context];</code></pre>
</blockquote>
<p>4. 렌더링 버퍼를 만듭니다. 이것은 마아도 백 버퍼일것입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/412/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac mini server를 소스서버로 세팅하기.</title>
		<link>http://blog.eonil.com/post/502</link>
		<comments>http://blog.eonil.com/post/502#comments</comments>
		<pubDate>Sat, 04 Dec 2010 07:20:55 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/UNIX]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=502</guid>
		<description><![CDATA[이번에 소스서버를 세팅했습니다. 환경을 바꾸고 집중해서 했더니 생각지도 못했던 아이디어가 솟아나면서 생각보다 쉽게 이틀만에 셋업을 했네요. 나중을 위해 그 과정을 적어둡니다. 소스서버 세팅은 크게 몇 가지 단계로 구분됩니다. OS 설치 네트워크 구성 소스서버 구성 (SVN) 데이터베이스 구성 (PostgreSQL) 이슈서버 구성 (redmine) 빌드서버 구성 제목은 소스서버 세팅이라 썼지만, 하는김에 필요한 것들을 다 하기로 했어요. OS 설치 [...]]]></description>
			<content:encoded><![CDATA[<p>이번에 소스서버를 세팅했습니다. 환경을 바꾸고 집중해서 했더니 생각지도 못했던 아이디어가 솟아나면서 생각보다 쉽게 이틀만에 셋업을 했네요. 나중을 위해 그 과정을 적어둡니다.</p>
<p>소스서버 세팅은 크게 몇 가지 단계로 구분됩니다.</p>
<ol>
<li>OS 설치</li>
<li>네트워크 구성</li>
<li>소스서버 구성 (SVN)</li>
<li>데이터베이스 구성 (PostgreSQL)</li>
<li>이슈서버 구성 (redmine)</li>
<li>빌드서버 구성</li>
</ol>
<p>제목은 소스서버 세팅이라 썼지만, 하는김에 필요한 것들을 다 하기로 했어요.</p>
<h1>OS 설치</h1>
<p>맥 미니에는 Mac OS X Snow Leopard Server가 동봉됩니다. 사실 이것 때문에 맥 미니를 선택한 것이지요. 아시다시피 해줄 것이 아무것도 없습니다.</p>
<p>하지만 유의사항은 있습니다. 먼저, LDAP를 사용할지 안할지를 결정해야 합니다. 저는 서버가 한대뿐이므로 복잡한 LDAP를 사용하지 않고 로컬 계정으로 모든 것을 해결하기로 결정했기에, LDAP를 사용하지 않도록 설정했습니다. 또한, 초기에 서버 이름을 결정해 주는 것이 좋습니다. 나중에 바꾸려면 생각보다 힘듭니다.</p>
<p>설치 직후에는 반드시 OS 업데이트를 해 줍니다. 다른 것도 있지만, 동봉된 서버 툴을 업데이트해야 하기 때문입니다. 다수의 툴이 동봉되어 있는데, 애플에서 구성한 것과 다르게 하면 애플의 GUI툴이 제대로 동작하지 않게 됩니다. 혹시 꼬졌다고 생각하는 분은 생 BSD나 리눅스를 직접 구성하시는 것이 좋겠군요~</p>
<h1>네크워크 구성</h1>
<p>인터넷에 연결된 외부 라인이 하나 있습니다. 이 라인에 공유기를 연결해 서브넷을 구성하기로 했습니다. 공유기 설정을 사용해 NAT만 가동시키고, DHCP는 끕니다. 이제 공유기는 단순 허브에 가까워졌습니다. DHCP와 DNS를 미니서버가 하도록 해서 커스텀 도메인 주소를 사용해 접속할 수 있도록 하기 위함입니다.</p>
<p>공유기 주소는 보통 <code>192.168.0.1</code>일 것입니다. 서브넷 마스크는 <code>255.255.255.0</code>입니다. 미니서버가 네임 서비스를 제공해야 하기에 <code>192.168.0.250</code>이라는 고정 IP를 할당합니다. 공유기 주소를 게이트웨이로 할당하고, 동일한 서브넷을 할당합니다. 네임서버는 자신의 주소, 즉 <code>192.168.0.250</code>을 사용합니다.</p>
<p>OS 설치후, 독을 보면 Server Admin이라는 툴이 있습니다. 앞으로 거의 모든 서버 구성을 여기에서 합니다. 서버 어드민을 켜고 서버 이름을 적절하게 고쳐줍니다. 그리고 DNS와 DHCP를 체크해 추가해줍니다.</p>
<p>DNS를 먼저 세팅합니다. DNS는 원하는 것에 따라 다르겠지만, 기본 구성은 여러가지 서비스를 제공하려는 제 목적에 맞지 않습니다. 그래서 기본 구성을 지우고 다음과 같이 구성했습니다. (네트워크 이름은 임의로 변경)</p>
<blockquote>
<pre><code>Primary Zone
eonil.lab.

A
svn
192.168.0.250

A
redmine
192.168.0.250
</code></pre>
</blockquote>
<p>오, 이건 버클리 파일 형식이 아니니 분노는 잠시 거두시구요. 그냥 알아보기 편하게 제가 나름대로 쓴 것 뿐입니다. 리버스 영역도 할당했구요. <code>CNAME</code>이 좋다는 말은 들었지만, 제가 전문가도 아니고 그냥 <code>A</code>로 했습니다. <code>CNAME</code>은 웬지 잘 안되더라구요. 여튼, 이렇게 구성하면 <code>svn.eonil.lab</code>과 <code>redmine.eonil.lab</code>으로 미니서버에 접근이 가능해집니다. 봉쥬르는 사용하지 않고, 포워딩 네임서버는 ISP가 지정한 서버와 구글 네임서버로 지정합니다.</p>
<p>이어서 DHCP도 구성합니다. <code>192.168.0.100</code>~1<code>92.168.0.200</code>까지의 IP를 예약해두고, 서브넷을 <code>255.255.255.0</code>, 라우터는 <code>192.168.0.1</code> (공유기)로 지정합니다. 네임서버는 <code>192.168.0.250</code>만으로 지정합니다.</p>
<p>구성이 잘 되었는지 확인하기 위해서는 <code>dig</code>와 <code>nslookup</code>툴을 사용합니다. 이 때 주의해야 할 것은 확인하기 전에 반드시 <code>dscacheutil -flushcache</code> 명령을 사용해 DNS 캐시를 비워야 한다는 것입니다.</p>
<p>이제 미니서버가 살아있는 한 이 공유기에 붙여지는 머신들은 모두 자동으로 네트워크 구성이 됩니다.</p>
<h1>소스서버 구성 (SVN)</h1>
<p>소스서버는 CVS, SVN, Git 등 여러가지 종류가 있습니다. Git이 좋다고 들었지만, Xcode가 지원하지 않기에 SVN으로 선택했습니다. SVN은 Mac OS X에 미리 설치되어 있으므로 아무것도 해주지 않아도 됩니다. 끝!</p>
<p>&#8230;이면 좋겠지만, 툴이 설치되어 있는 것 뿐이지 저장소나 GUI툴은 없기 때문에 직접 구성해야 합니다. 웹을 찾으면 금방 나오는 매뉴얼대로 만들었습니다.</p>
<blockquote>
<pre><code>mkdir /Library/Subversion/Repository
cd /Library/Subversion/Repository
svnadmin create ./app1</code></pre>
</blockquote>
<p>하면 프로젝트 폴더가 만들어집니다. 프로젝트 폴더의 이름은 HTTP로 호스팅될 것이기 때문에 소문자로 했습니다. OS X의 디렉토리 구조를 보면 폴더에는 &#8220;Word Word&#8221; 방식의 케이싱을 사용하지만 폴더 안의 디렉토리에는 &#8220;word&#8221; 방식으로 이름을 짓습니다. 폴더와 디렉토리의 차이가 뭐냐구요? 뭐랄까 설명하기 힘드네요. 파인더에서 보이면 폴더라고 할까요&#8230; 이건 극히 복잡한 규칙으로 구성된 제 네이밍 결벽증에 연관되어 있어서 더 자세히 설명하지는 않겠습니다. 하여튼 이렇게 하면 저장소가 만들어지고 기본 구조가 생깁니다.</p>
<p>이 상태 그대로 이 폴더를 SSH를 통해 서빙할 수 있습니다. 하지만 그렇게 하면 치명적인 단점이 있습니다. 프로젝트 저장소의 경로를 커스터마이즈 할 수 없고, 윈도우에는 SSH 연결이 가능한 기본 쉘이 없으므로, 윈도우 클라이언트에서는 연결하기가 매우 까다로워진다는 것입니다. 이러한 윈도우 클라이언트의 하나인 TortoiseSVN은 Putty를 통한 SSH 연결을 사용해야 하는데, 가장 큰 문제는 Putty를 깔아줘야 한다는 것입니다. 그 외에도 인증키를 받아서 설치해야 한다든가 하는 것들이 있기에 그냥 한번 어렵고 말지 하는 생각에 HTTPS로 서빙하기로 했습니다.</p>
<p>HTTPS로 서빙하려면 HTTP 데몬이 필요합니다. 그래서 Server Admin 툴에서 Web을 켜 줍니다. 그러면 아파치가 가동됩니다. Web 설정은 기본 사이트 하나가 미리 구성되어 있는데, 이 구성은 내버려 두고, 사이트를 하나 더 만들어서 SSL로 설정하고 호스트 이름을 svn이라 줍니다. (이 이름은 식별자로 쓰이므로 중요합니다.) 호스팅 폴더는 아까 만든 <code>/Library/Subversion/Repository</code>를 지정해 줍니다. (프로젝트가 아닌 저장소 루트임에 주의하세요.) 그리고 Web Server Aliases에 <code>svn.eonil.lab</code> (FQDN이 아님에 주의하세요.)를 추가해주면 이 주소로 연결했을 때 이 사이트가 뜨게 됩니다. 잡스러운 옵션을 다 지우고, WebDAV만 켜줍니다. 그리고 <code>mod_dav.so</code>(?, 이게 맞던가?;;)와 <code>mod_authz_svn.so</code>를 체크해 줍니다.</p>
<p>이제 웹 서버는 구성되었으니 여기에 접근할 수 있도록 계정 인증을 설정합니다. 먼저 System Preferences를 열어 Subversion Users라는 그룹을 만들어 SVN을 사용할 유저들을 몽땅 집어넣습니다. 그리고 Workgroup Manager를 열어 이 그룹의 short name을 svn으로 바꿔줍니다. 아까의 Server Admin에서 만든 웹 서버 설정으로 돌아가 subversion이라는 이름의 새 렐름을 만든 다음, svn 그룹에 WebDAV의 browse/read/write 권한을 줍니다.</p>
<p>이제 터미널을 열고, <code>/etc/apache2/sites/</code> 로 갑니다. 여기에 보면 <code>.conf</code> 파일이 다수 있는데 아까 만든 사이트의 파일이 있을 겁니다. 이걸 vi로 열어 뒷쪽을 보면 <code>&lt;Location "/svn/"&gt;</code>라는 라인이 있습니다. 이 로케이션은 URL 서브경로입니다. 저는 다른 경로를 원했기에  <code>&lt;Location "/project/"&gt;</code>로 바꿨습니다. 이 경로를 바꾸는 법을 알아내기 위해 고생을 좀 했지요. 그리고 요소의 안에 다음 라인을 추가합니다.</p>
<blockquote>
<pre><code>DAV svn
SVNParentPath /Library/Subversion/Repository</code></pre>
</blockquote>
<p>이를 저장*하고, 서버 어드민 툴에서 웹 서버를 껐다가 킵니다. 그러면 이제 <code>https://svn.eonil.lab/project/app1</code>로 연결하면 SVN 저장소가 보일 것입니다. 와우!</p>
<p>*이렇게 웹사이트 세팅을 수동으로 저장하면 서버 어드민 툴을 사용할 때 이 사항이 삭제되거나 리셋될 수 있습니다. 서버 어드민 툴을 사용한 뒤에는 이 설정이 변하지 않았는지 다시 확인해야 합니다. 솔직히 이건 좀 꼬졌네요.</p>
<p>SVN설치에 관한 것은 애플의 문서:<br />
<a href="http://developer.apple.com/tools/subversionxcode.html">http://developer.apple.com/tools/subversionxcode.html</a><br />
를 참조했습니다. 아 이 문서는 구버젼이군요. 신버젼은:<br />
<a href="http://developer.apple.com/library/mac/#featuredarticles/SubversionXcode3/">http://developer.apple.com/library/mac/#featuredarticles/SubversionXcode3/</a> 에 있습니다. 신버전이 스크린샷도 동봉되어 있어서 더 보기가 좋더군요. 모듈 이름이 애매하게 되어 있는것만 제외하면 꽤 좋습니다. 제가 나름 기억나는대로 쓰긴 했지만 뭔가 빠져있을지도 모르니 그때는 저 원본 문서를 참조해 주세요.</p>
<h1>데이터베이스 구성 (PostgreSQL)</h1>
<p>Mac OS X 서버에 MySQL이 미리 설치되어 있었지만, 오라클에 인수된 뒤 마구 나대는데다, 트랜젝션을 걸면 극적으로 성능이 떨어지고, 데이터 유실까지 있다는 말에 최근에 알게 된 <a href="http://www.postgresql.org/">PostgreSQL</a>을 사용하기로 했습니다. 나온지 20년이 넘었다던데, 안정성 하나는 믿어줄만할겁니다.</p>
<p>문제는 오피셜 맥 버전이 없고, 사제 포트만 있는데, 그 중에 GUI를 제공하는 버전이 상당히 이상하다는 겁니다. 설치는 엄청나게 오래 걸리고, GUI는 윈도우같이 생겼어요. 아무래도 뭔가 크로스플랫폼 미들웨어를 사용한 저질 툴로밖에 안보였습니다. 그래서 다른 버전을 찾았죠. 맥이 FreeBSD기반이긴 하지만 FreeBSD 포트가 돌아가지는 않죠. pink나 MacPorts가 있지만, 써본적이 없어서 그닥 땡기지 않더군요. 하지만 결국 괜찮은 걸 찾아냈습니다. <a href="http://www.postgresqlformac.com/">PostgreSQL for Mac</a>입니다. 처음에는 허접한 홈페이지 때문에 망설였지만, DMG를 마운트했더니 깔끔한 폴더 화면이 나타나더군요. 오~ 믿음이 갑니다. GUI툴은 완전 별로였지만, 대신 설치가 번개같이 빠르고, 제대로 동작했습니다. 그리고 서버 모니터링하는 System Preference Pane을 추가해 주는데 부실하지만 유용하더군요. 설치 후, 설치된 폴더로 이동해 <code>psql -U postgres</code>를 실행합니다.</p>
<blockquote>
<pre><code>ALTER USER postgres WITH PASSWORD 'your password';</code></pre>
</blockquote>
<p>를 실행해 DB내 수퍼유저인 <code>postgres</code>에 암호를 걸어주고, 세팅 파일을 손보아 모든 영역에서 암호를 사용해야 접근할 수 있도록 했습니다. 기본값은 어디에서나 암호 없이 아이디만으로 접근이 가능하도록 되어 있으므로, 꼭 설정해줘야 합니다.</p>
<h1>이슈서버 구성 (redmine)</h1>
<p>오오 이제 대망의 이슈서버입니다. 이슈서버는 여러가지 제안이 있었습니다. FileZilla, mantis, Trac, redmine 등이었죠. 저희는 돈이 없기에 Perforce나 JIRA같은건 꿈도 못꿉니다.</p>
<p>그 전에는 FileZilla를 썼었는데요, 아시다시피 UI가 그리 좋지 않습니다. 그리고 결정적으로 한글이 지원되지 않아서 영어 울렁증이 있는 아티스트들은 쓰질 못하더군요. 결국 redmine으로 결정이 되었는데요, 그래서 여러가지 장점에도 불구하고, redmine으로 결정된 가장 큰 이유는 한글화가 가장 잘 되어 있었기 때문입니다 ;)</p>
<p>지금부터 redmine을 설치한 과정을 알려드립니다. SVN과는 달리, 기본적으로 설치가 되어 있지 않기에, 맨땅에 헤딩을 좀 해야 했습니다. 헤딩한 에피소드 중에 하나 때문에 svn+ssh를 포기하게 되었죠. 사실 원래는 간단하게 구성 가능한 svn+ssh을 강압적으로 밀어부치려 했지만, redmine에서 SVN에 접근할 때마다 kerberos 인증이 실패하는 일이 벌어지더군요. localhost가 kerberos 인증에 실패하면 어떻게 될까요? 저는 원격 관리 화면이 멈춰버리고 domain name resolving이 계속 실패하는 이유를 알아내는데 2시간쯤 걸렸습니다. 결국 미니서버에 USB 키보드와 마우스, DVI모니터를 연결해야 했습니다. 나중에 안 사실이지만, 이게 아마 interactive 모드 인증 때문인가 그것 때문일 겁니다. 그냥 HTTP가 만능임을 받아들이는게 속편했습니다.</p>
<p>redmine은 백엔드 DB를 사용하는 루비 앱입니다. 그러니 루비와 백엔드 DB를 먼저 설치해야 합니다. 루비는 Mac OS X에 기본 설치되어 있습니다. 시스템 업데이트를 받아서인지 몰라도 무려 최신버젼이더군요! DB는 이것을 위해 아까 설치한 PostgreSQL을 사용합니다.</p>
<p>레드마인을 설치하기 위해서는 이 두가지 외에도 여러가지 툴이 필요합니다.</p>
<ul>
<li>rails</li>
<li>rack</li>
<li>rake</li>
<li>fastthread</li>
<li>passenger (웹 서버 어댑터)</li>
<li>postgres (DB 어댑터)</li>
</ul>
<p>다행인것은 대부분 다 기본으로 설치되어 있다는 겁니다. 없는 것은 rack과 passenger 뿐입니다. 다음 명령으로 이 둘을 설치합니다.</p>
<blockquote>
<pre><code>sudo gem install rack -v=1.0.1
sudo gem install passenger</code></pre>
</blockquote>
<p>패신저는 루비가 아닌 네이티브 소스로 설치됩니다. 그래서 컴파일을 해 주어야 하는데, 이를 위해서는 컴파일러 툴이 필요합니다. 컴파일러는 설치가 되어 있지 않은데, 설치하려면 Mac OS X SDK 를 설치하는 것이 가장 간편합니다. (iOS SDK를 설치해도 됩니다. 사실상 같거든요.</p>
<p>SDK를 설치했으면</p>
<blockquote>
<pre><code>sudo passenger-install-apache2-module</code></pre>
</blockquote>
<p>를 실행해 컴파일합니다. 컴파일이 끝나면 <a href="http://www.fngtps.com/passenger-preference-pane">http://www.fngtps.com/passenger-preference-pane</a>에서 받을 수 있는 System Preference Pane을 설치합니다.</p>
<p>postgres DB 어댑터도 소스 컴파일을 필요로 합니다. 이것은 젬을 받자마자 컴파일을 수행하므로 꼭 SDK 설치후에 설치해야 합니다.</p>
<blockquote>
<pre><code>sudo gem install postgres</code></pre>
</blockquote>
<p>일단 사전조건이 완성되었으면 redmine을 설치합니다. 레드마인 웹사이트에서 최신 안정 버전을 받아서 압축을 풀고, redmine 디렉토리를 <code>/Library/Rails/</code> 안으로 집어넣습니다. 다음 터미널을 열어, <code>psql -U postgres</code>를 실행한 후 레드마인 유저와 DB를 만듭니다.</p>
<blockquote>
<pre><code>CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'your_password' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;</code></pre>
</blockquote>
<p>그리고 데이터베이스 어댑터를 세팅합니다. 레드마인 폴더로 이동한 뒤, config 폴더 안에 있는 <code>database.yml.example</code> 파일을 <code>config/database.yml</code>로 복사합니다. 그리고 파일을 열어 기존 내용을 다 지우고 내용을 다음과 같이 고칩니다. (DB가 레드마인과 같은 서버에 있기에 레드마인 주소를 사용합니다.)</p>
<blockquote>
<pre><code>production:
adapter: postgresql
database: redmine
host: redmine.eonil.lab
username: redmine
password: your_password
encoding: utf8</code></pre>
</blockquote>
<p>다음, 셋업을 하기 전에 레드마인용의 계정을 하나 만듭니다. 원래는 그룹으로 만들려고 했지만, SVN 접근시 HTTPS를 통과하지 못하더군요. 사실 SSL인증서가 사제라 그런거지만, 사제 인증서를 트러스트하는 법을 알아내기는 귀찮아서 그냥 사용자 계정으로 만들고 svn 그룹에 추가시켰습니다.</p>
<p>터미널을 열어 레드마인 디렉토리로 이동한 후, 셋업을 합니다.</p>
<blockquote>
<pre><code>rake generate_session_store
RAILS_ENV=production rake db:migrate
RAILS_ENV=production rake redmine:load_default_data
sudo chown -R redmine:redmine files log tmp public/plugin_assets
sudo chmod -R 755 files log tmp public/plugin_assets</code></pre>
</blockquote>
<p>셋업이 끝나면 루비의 웹서버를 임시로 가동해 관리자 계정을 세팅합니다.</p>
<blockquote>
<pre><code>ruby script/server webrick -e production</code></pre>
</blockquote>
<p><code>http://localhost:3000/</code>로 접속하면 레드마인이 보입니다. 어드민 계정의 초기값은 <code>admin/admin</code>입니다. 암호를 바꾸어 주고 <code>Ctrl+Z</code>로 이 서버를 닫습니다.</p>
<p>그리고 정식 서빙을 하기 위해 아파치가 레드마인을 서빙하도록 해야 합니다. 셋업과정은 이렇습니다.</p>
<ol>
<li>패신저 모듈을 아파치에 로드한다.</li>
<li>새로운 웹 사이트를 생성한다.</li>
<li>이 사이트가 레드마인 소스를 호스팅하게 한다.</li>
<li>패신저에 레드마인를 태운다.</li>
</ol>
<p>여기서부터 굉장한 삽질을 했습니다. 패신저를 사용하는 법을 정확하게 알 수가 없었거든요.</p>
<p>일단 아파치 세팅을 조정해 패신저 모듈을 로드합니다. <code>/etc/apache2/httpd.conf</code>를 보면 <code>LoadModule</code> 섹션이 있는데 마지막에 다음 라인을 추가합니다.</p>
<blockquote>
<pre><code>LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-3.0.0/ext/apache2/mod_passenger.so
PassengerRoot /Library/Ruby/Gems/1.8/gems/passenger-3.0.0
PassengerRuby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</code></pre>
</blockquote>
<p>그리고 서버 어드민 툴을 열어 새로운 웹 사이트를 하나 만듭니다. 호스트 이름은 redmine, 웹 폴더는 <code>/Library/Rails/redmine/public</code> 으로 줍니다. 이게 중요한지는 모르겠는데, 여튼 public 폴더를 호스팅하도록 해야 한답니다. 그리고 잡스런 옵션을 다 꺼 주고, SSL를 켜 준 다음, 웹 서버 별칭을 <code>redmine.eonil.lab</code>으로 줍니다.</p>
<p>그 다음 System Preferences에서 Passenger를 열어 이 <code>/Library/Rails/redmine/public</code> 폴더를 드래그해 추가합니다. Aliases를 <code>redmine.eonil.lab</code> 으로 설정하고 Run in은 Production으로 바꾼뒤 리스타트합니다. 웹서버도 다시 껏다 켜 줍니다.</p>
<p>아, 그리고 웹 사이트 설정을 변경했으니 SVN의 수동 사이트 설정을 한 번 더 확인하는 것도 잊지 말기 바랍니다.</p>
<p>레드마인 인스톨은 다음 문서들을 참조했습니다:</p>
<ul>
<li><a href="http://www.redmine.org/wiki/1/RedmineInstall">http://www.redmine.org/wiki/1/RedmineInstall</a></li>
<li><a href="http://www.redmine.org/wiki/1/RedmineInstallOSXServer">http://www.redmine.org/wiki/1/RedmineInstallOSXServer</a></li>
</ul>
<p>Passenger 세팅은 애플의 가이드도 있습니다:<br />
<a href="http://developer.apple.com/library/mac/#featuredarticles/PhusionRails/">http://developer.apple.com/library/mac/#featuredarticles/PhusionRails/</a></p>
<h1>빌드서버 구성</h1>
<p>빌드 서버 구성이란 서버에서 자동으로 패키징까지 완료하는 것을 말합니다. 사실 SDK를 설치하는 것으로 빌드 환경은 완비됩니다. 이제 SVN에서 최신 소스를 다운로드해 빌드하고, 별도의 서버에 호스팅하는 스크립트를 만들어야 하는데, 이는 각 프로젝트마다 다를 수 밖에 없습니다. 하지만 기회가 된다면 iOS 앱용 프로젝트를 위주로 한 번 알아보겠습니다!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/502/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>헝가리안 표기법의 재발견</title>
		<link>http://blog.eonil.com/post/479</link>
		<comments>http://blog.eonil.com/post/479#comments</comments>
		<pubDate>Sat, 06 Mar 2010 13:56:15 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=479</guid>
		<description><![CDATA[오늘 &#8216;조엘 온 소프트웨어를 넘어서&#8217;를 보았습니다. 많은 내용이 &#8216;조엘 온 소프트웨어&#8217;의 재탕이라 실망한 부분도 있었지만, 새로운 내용도 몇 있었고, 꽤 가치있는 내용입니다. 지난 포스트에서 헝가리안 표기법을 무시했었는데, 이 책을 읽고 나니 다시 생각해야겠다는 생각이 들었습니다. 사실 이 책을 구매한 이유의 중 하나가 이 챕터를 보기 위해서였습니다. 내용을 요악하면 헝가리안 표기법의 원래 목적은 변수의 타입을 구분하기 [...]]]></description>
			<content:encoded><![CDATA[<p>오늘 <strong>&#8216;조엘 온 소프트웨어를 넘어서&#8217;</strong>를 보았습니다. 많은 내용이 &#8216;조엘 온 소프트웨어&#8217;의 재탕이라 실망한 부분도 있었지만, 새로운 내용도 몇 있었고, 꽤 가치있는 내용입니다.</p>
<p><a href="http://blog.eonil.com/wp-content/uploads/2010/03/IMG_0426-e1267884207170.jpg"><img class="alignnone size-large wp-image-484" title="IMG_0426" src="http://blog.eonil.com/wp-content/uploads/2010/03/IMG_0426-e1267884207170-768x1024.jpg" alt="" width="323" height="430" /></a></p>
<p><a href="http://blog.eonil.com/archive/2010/02/21/언어와-생산성/">지난 포스트</a>에서 헝가리안 표기법을 무시했었는데, 이 책을 읽고 나니 다시 생각해야겠다는 생각이 들었습니다. 사실 이 책을 구매한 이유의 중 하나가 이 챕터를 보기 위해서였습니다.</p>
<p>내용을 요악하면 헝가리안 표기법의 원래 목적은 변수의 <strong>타입</strong>을 구분하기 위한 것이 아니라, 변수의 <strong>종류</strong>를 구분하기 위한 것이었다는 겁니다. 이것이 MS 내에 존재하는 2류 프로그래머들에게 제대로 전달되지 않아 지금 오명을 뒤집어쓰고 있다는 것이죠.</p>
<p>헝가리안 표기법을 처음 봤을 때 세상에 뭐 이런 멍청한 표기법이 있나 하는 생각이 들 정도였습니다. 잘못 알려진 헝가리안 표기법은 컴파일러가 완벽하게 검사해주는 기본 타입을 중복해서 표기합니다.</p>
<blockquote>
<pre><code>// Prefix 'ui' means 'unsigned int'.
unsigned int uiVar1 = 0;
unsigned int uiVar2 = 0;</code></pre>
</blockquote>
<p>완벽한 낭비인데다가 가독성을 향상시키지도 못합니다. 원래는 이런 것입니다.</p>
<blockquote>
<pre><code>// Prefix 'x' means 'x axis'.
// Prefix 'y' means 'y axis'.
unsigned int xVar1 = 0;
unsigned int yVar1 = 0;</code></pre>
</blockquote>
<p>같은 타입의 변수라 해도 다른 영역에서 쓰인다면 이들은 구분되어야 하고, 시각적으로도 잘 인지되어야 한다는 것입니다. 조엘은 헝가리안 표기법을 매우 좋아하는데 헝가리안 표기법에도 문제는 있습니다. 그것은 프리픽스를 약어로 사용한다는 것입니다.</p>
<blockquote>
<pre><code>// Prefix 'uwc' means 'UI Window Coordinate'.
function func1(int uwcVar1);</code></pre>
</blockquote>
<p>약어는 시간이 지나면 작성자도 못알아보는 암호가 되고, 결국 위와 같이 내용을 중복해서 설명하는 주석을 달아야 합니다. 이것보다는 단어 전체를 사용하는 애플 방식이 더 낫습니다.</p>
<blockquote>
<pre><code>(void)func1: (int)userWindowCoordinateVar1;</code></pre>
</blockquote>
<p>너무 깁니다. 그래서 타이핑이 힘들죠. 하지만 읽는 것은 더 쉽습니다. 작성 후 몇 달이 지났다고 생각하면 더 생각할 필요도 없죠. 애플의 길다란 네이밍 방식에 대해 &#8216;너무 길다&#8217;라고 불평하는 사람은 코드 유지관리를 해본적이 없는 사람입니다. 작성할 때 몇 글자만 더 타이핑하면 두고두고 보기 쉬운 코드를 만들 수 있습니다. 게다가 Xcode, Eclipse, VS.NET 등 대부분의 메이저 IDE는 강력한 이름 완성 기능을 제공합니다. 그래서 실제로 타이핑하는 양은 별 차이가 없습니다. 이름 자동 완성 기능이 없는 편집기를 쓰고 계시다면 할 말이 없네요. 저는 기억력이 모자라서 그런 편집기로는 코딩 못합니다.</p>
<h1>헝가리안 표기법의 가치</h1>
<p>중요한 것은 컨셉입니다. 변수명을 일종의 수식어로 데코레이트하는 것이 유용하다는 것을 알지만 이 수식어로 무엇을 사용하는 것이 좋은지는 잘 몰랐습니다. 헝가리안 표기법은 이 수식어로는 <strong>변수가 사용되는 영역의 종류</strong>를 지정하는 것이 적당하다는, 경험에서 우러나온 지혜를 알려줍니다.</p>
<h1>컴파일러 형 검사 남용</h1>
<p>사실 변수의 종류를 구분하기 위해 별도의 타입을 만들고 컴파일러에게 이러한 타입 체크를 맡겨버리는 방법도 있습니다. 클래스가 하는 일이 그것이죠. 하지만 기본적인 프리미티브 타입에 대해서까지 이러한 방식을 사용하는 것은 코드 작성시 소모되는 오버헤드가 많아 생산성을 떨어뜨리게 될 것 같습니다. 일종의 컴파일러 형 검사 남용이죠. 형 검사는 형 검사일 뿐 로직을 보증할 수는 없습니다. 결국 어느정도의 복잡도는 프로그래머 머리속에서 처리되어야 합니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/479/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>간단한 일인데요&#8230; 어쩌구 저쩌구&#8230;</title>
		<link>http://blog.eonil.com/post/471</link>
		<comments>http://blog.eonil.com/post/471#comments</comments>
		<pubDate>Thu, 25 Feb 2010 23:45:48 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Gossip]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=471</guid>
		<description><![CDATA[일을 하다 보면 이런 멘트를 자주 접하게 됩니다. 이거 간단한 일인데요&#8230; 어쩌구 저쩌구&#8230; 금방 되겠죠? 일단 이런 말을 들으면 대번에 떠오르는 생각은 한가지입니다. 어떻게든 싸게 부려먹고 싶어하는구나! 물론 이 생각을 표현하지는 않습니다. 하지만 제 계산으로는 간단하고 금방되는 일은 가격이 더 비싸집니다. 간단한 일 간단한 일이라고 하지만 실제로는 간단한 일은 없습니다. 그렇게 간단하면 직접 했겠죠. 직접 [...]]]></description>
			<content:encoded><![CDATA[<p>일을 하다 보면 이런 멘트를 자주 접하게 됩니다.</p>
<blockquote><p>이거 간단한 일인데요&#8230; 어쩌구 저쩌구&#8230; 금방 되겠죠?</p></blockquote>
<p>일단 이런 말을 들으면 대번에 떠오르는 생각은 한가지입니다.</p>
<blockquote><p>어떻게든 싸게 부려먹고 싶어하는구나!</p></blockquote>
<p>물론 이 생각을 표현하지는 않습니다. 하지만 제 계산으로는 간단하고 금방되는 일은 가격이 더 비싸집니다.</p>
<h1><span style="font-weight: normal;">간단한 일</span></h1>
<p>간단한 일이라고 하지만 실제로는 간단한 일은 없습니다. 그렇게 간단하면 직접 했겠죠. 직접 처리할 수 없을 정도로 복잡하거나, 힘들거나 어렵기에 외주가 나가는 거죠. 이 경우, 작업자는 두가지를 생각해야 합니다.</p>
<ul>
<li>발주자가 일의 복잡성을 모릅니다. 발주자에게 전문적인 수준의 교육을 해 주어야 합니다.</li>
<li>발주자가 일의 복잡성을 알고 싶어하지 않습니다. 즉, 작업자가 대신 처리해주어야 합니다.</li>
</ul>
<p>보통 발주자가 교육을 원하는 케이스는 거의 없기에, 대부분의 작업자가 할 일이 늘어나는 것입니다. 특히, 이 경우, 발주자가 일처리에 대한 지식이 없다는 것이 확실하기 때문에 복잡성을 추상화하고, 경우에 따라서는 동의 없이 결정을 하는 리스크도 안아야 합니다. 연속되는 컨펌과 크리틱, 재작업은 기본입니다.</p>
<p>뭐 다 충분히 예상 가능한 일이고, 처리 가능하지만, 비용은 최소한 2배 이상 들어갑니다. <em>&#8216;간단한 일&#8217;</em>은 실제로는<em> &#8216;저는 아무것도 모르니 알아서 잘해주세요&#8217;</em>입니다. 물론 실제로 결정권을 주면 정말 간단한 일이 되겠지만, 결정권을 주는 클라이언트는 거의 없고, 대부분은 그날그날의 기분에 따라 결정이 바뀝니다. 이런 일은 최소한 2배의 비용을 받아야 하며, 기획서도 부실하고 이상할 정도로 리젝트 비율이 높으므로, 수지가 맞으려면 3배 이상은 받아야 합니다.</p>
<h1><span style="font-weight: normal;">금방 되는 일</span></h1>
<p>한 가지 잘 알려지지 않은 사실은, 모든 일에는 적절한 작업기한이 있다는 것입니다. 그리고 이 기한에서 늘거나 줄어드는 것은 양쪽으로 비용이 추가됩니다. 보통 발주자는 기한이 늘면 비용이 추가되고, 기한이 줄면 비용이 줄어드다고 생각합니다. 하지만 그렇지 않습니다. 기한이 늘면 어떻게든 작업이 연장되므로, 신경쓰고 서비스해야 하는 부분이 늘어납니다. 작업자의 시간을 구매하는 것이니 당연히 비용이 추가됩니다. 하지만 적정기간보다 기한이 줄면, 작업자는 절대마감에 맞춰 없는 시간을 만들어내는 마술을 부려야 합니다. 그런데 클라이언트가 &#8216;금방 될 것&#8217;이라고 언급하는 경우, 대부분은 발주자가 업무에 걸리는 시간을 잘 모르기 때문입니다. 그래서 <em>&#8216;금방 되는 일&#8217;</em>을 원하는 경우, 이 말의 의미는 <em>&#8216;어떻게든 알아서 마감을 맞춰주세요!&#8217;</em> 라는 뜻입니다.</p>
<p>이 경우, 추가되는 비용은 곤란할 정도로 계산하기 어렵습니다. 작업자의 여가와 휴식 시간을 사용해야 하기 때문이며, 최악의 경우, <em>&#8216;정신과 시간의 방&#8217;</em>을 사용해야 하기 때문입니다.</p>
<h1><span style="font-weight: normal;">비용 추가</span></h1>
<p>사실 발주자가 이러한 사항을 잘 모르지는 않습니다. 특히, 시간과 비용은 어디에서나 중요하기 때문에, 제대로 된 발주자라면 이런 부분에는 탁월한 감각을 가지고 있습니다. 이들은 이런 단어를 함부로 언급하지 않습니다. 이런 단어를 언급해야 하는 상황은 고비용을 불러오기 때문에, 항상 적절한 난이도와 기간을 계산합니다.</p>
<p>그래도 이러한 &#8216;간단한&#8217;이나 &#8216;금방 되는&#8217; 같은 단어를 언급하는 것은 실제로 &#8216;알아서&#8217;, &#8216;빠르게&#8217;를 원하기 때문입니다. 높은 비용을 청구해도 이상하지 않습니다.</p>
<p>간혹 가다 이런 단어로 수식하면 실제로 일의 복잡성이 줄어보여서 비용을 싸게 할 수 있지 않을까- 하고 생각하는 초보 발주자도 있는데, 그렇게 보일지는 몰라도 실제로 일의 복잡도가 줄어드는 것은 아니므로, 발주자가 실제로 이런 생각을 갖고 있다면 계약이 성립되지 않습니다. 이 경우 작업자는 위와 같은 사항을 언급해 실제는 어떻다는 것을 알려야 합니다. 대부분의 경우, 작업자 입장에서는 발주자가 어느 정도의 감을 갖고 있는지 알 수 없으므로 일단 항상 이런 사항들을 언급해야 합니다. 이런 것을 다 알고도 낮은 비용으로 일을 해결하려 한다면 정당한 가격을 지불하려 하지 않는 &#8216;악덕 업주&#8217;일 따름입니다. 그런사람과는 일을 하지 마십시오.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/471/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stop on Objective-C Exceptions</title>
		<link>http://blog.eonil.com/post/459</link>
		<comments>http://blog.eonil.com/post/459#comments</comments>
		<pubDate>Sun, 21 Feb 2010 21:55:33 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=459</guid>
		<description><![CDATA[Xcode에는 Stop on Objective-C Exceptions라는 옵션이 있습니다. 처음에 이 옵션을 보고  멋모르고 이걸 켰다가 지금까지 고생을 했네요. 일단, 이 옵션은 로우레벨 예외에서 멈추는 옵션입니다. Cocoa는 Objective-C의 예외를 캐치해 적절한 예외 메시지를 생성해 보여줍니다. 그런데 이 옵션을 체크하면 예외가 생성된 그 순간에 디버거가 멈춥니다. 그래서 예외 메시지가 전혀 표시되지 않고 EXC_BAD_어쩌구 하는 메시지나 SIGABRT만 보이게 됩니다. 최악의 [...]]]></description>
			<content:encoded><![CDATA[<p>Xcode에는 Stop on Objective-C Exceptions라는 옵션이 있습니다. 처음에 이 옵션을 보고  멋모르고 이걸 켰다가 지금까지 고생을 했네요.<br />
<a href="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.22.15.png"><img class="size-full wp-image-460    alignleft" title="Screen shot 2010-02-22 at 오전 6.22.15" src="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.22.15.png" alt="" width="210" height="382" /></a></p>
<p>일단, 이 옵션은 로우레벨 예외에서 멈추는 옵션입니다. Cocoa는 Objective-C의 예외를 캐치해 적절한 예외 메시지를 생성해 보여줍니다.</p>
<p>그런데 이 옵션을 체크하면 예외가 생성된 그 순간에 디버거가 멈춥니다. 그래서 예외 메시지가 전혀 표시되지 않고 EXC_BAD_어쩌구 하는 메시지나 SIGABRT만 보이게 됩니다. 최악의 경우에는 아무것도 안나옵니다.</p>
<p><a href="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.23.47.png"><img class="alignnone size-full wp-image-461" title="Screen shot 2010-02-22 at 오전 6.23.47" src="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.23.47.png" alt="" width="365" height="36" /></a></p>
<p>로우 레벨 개발을 지원하기 위해 존재하는 옵션인거죠. 더 강력한 기능에 엑세스할 수 있도록 하는 옵션이지만, 평소에는 쓸 일이 없습니다.</p>
<h1>예외 메시지 없이 디버깅하기&#8230;</h1>
<p>너무 힘들었었습니다. 로우레벨 옵션을 켜놓고 지금까지 코코아에 원래 예외 메시지가 없는 줄 알았던 겁니다! 생각해보면 말이 안되는 거죠. 플랫폼 시스템용 API인데 예외 메시지가 전혀 없다는 건 있을 수 없는 일입니다. 그런데도 그려러니 하고 넘어갔던 건 이상한 프레임워크를 너무 많이 봐와서일겁니다.</p>
<p>이 문제를 발견하게 된 것은 Fast Enumeration 덕분입니다. <code>for...in</code>으로 컬렉션을 조회하고 있는데 조회문에서 계속 예외가 발생하는 거죠.</p>
<blockquote>
<pre><code>for(id &lt;Discrete&gt; e in elements)    // 여기에서 예외
{
    [e tick];
}</code></pre>
</blockquote>
<p>메시지도 없고, 모든 요소들을 다 검사해봐도 문제가 없었습니다. 4시간 정도를 고민하다가 그냥 잠들어버렸습니다. 좀 자다가 일어나서 다시 이걸 쳐다보니 조회 도중에 컬렉션을 수정하고 있다는 것이 생각났습니다. C#의 for&#8230;in에서는 조회 중 컬렉션을 수정하면 예외가 생겼죠. 곧바로 이런 기본적인 예외에 대한 메시지조차 표시하지 않는 이유가 뭘까? 하는 생각이 들었습니다. 그리고 예외 메시지가 없을리가 없다는 생각을 하게 됐죠. 그리고 생각난게 Stop on Objective-C Exceptions 옵션입니다.</p>
<p>생각난 김에 바로 이 옵션을 끄고 테스트를 해 봤죠.</p>
<p><a href="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.24.371.png"><img class="alignnone size-full wp-image-463" title="Screen shot 2010-02-22 at 오전 6.24.37" src="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.24.371.png" alt="" width="349" height="217" /></a></p>
<p>&#8216;컬렉션 조회 중 컬렉션을 수정하였기에 예외가 발생했습니다&#8217;라는 문구가 보이시나요? 제가 4달 동안 보고 싶었던 것도 이겁니다. 정말 반가워요! 지금가지의 어려웠던 세월이 힘겹게만 느껴집니다&#8230;</p>
<p>더 놀라운것은 이 옵션을 켰더라도 이 메시지를 볼 수 있다는 겁니다. 그냥 디버깅 컨티뉴를 하면 됩니다.</p>
<p><a href="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.25.31.png"><img class="size-full wp-image-464  alignnone" title="Screen shot 2010-02-22 at 오전 6.25.31" src="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.25.31.png" alt="" width="54" height="54" /></a><br />
그러면 옵션을 켜지 않았을 때와 마찬가지의 메시지를 보여줍니다.<br />
<a href="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.25.21.png"><img class="size-full wp-image-465  alignnone" title="Screen shot 2010-02-22 at 오전 6.25.21" src="http://blog.eonil.com/wp-content/uploads/2010/02/Screen-shot-2010-02-22-at-오전-6.25.21.png" alt="" width="347" height="226" /></a></p>
<p>물론 경우에 따라서 그냥 종료되는 경우도 있는데, 그런 경우는 정말로 해당 예외에 대한 메시지가 없는 경우이겠죠. 또한, 어떤 경우엔, 안좋아 보이는 로그가 계속 뜨는데 예외로 잡히지 않는 경우도 있습니다. 이 경우엔 이 옵션을 켜야만 예외가 잡힙니다.</p>
<h1>기본 세팅</h1>
<p>처음 이 옵션을 봤을 때, Xcode가 여러 언어를 지원하므로 Objective-C에 특화된 기능인지 알고 그냥 켰습니다. 물론 왜 기본으로 꺼져 있을까&#8230; 하는 의심이 있긴 했지만요. 덕분에 지금까지 예외 메시지 하나 없이 계속 개발을 했던 것이죠. 플렉스 빌더같은 이클립스 계열은 뭔가 많이 세팅해주지 않으면 제대로 작동하는게 없을 지경이라 버릇대로 했던 것이 이런 결과를 불러왔습니다.</p>
<p>역시 애플의 성향대로, 기본 세팅이 최적의 세팅이었습니다. 웬만해서는 아무것도 건드리지 않는 것이 좋습니다.</p>
<p>결과적으로 이 옵션은 정말 로우 레벨입니다. 강력한 대신 불친절하죠. 일단 한동안 옵션을 끄고 사용해봐야겠습니다. 필요할 때만 켜서 쓰도록 말이죠.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/459/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>언어와 생산성</title>
		<link>http://blog.eonil.com/post/452</link>
		<comments>http://blog.eonil.com/post/452#comments</comments>
		<pubDate>Sun, 21 Feb 2010 02:45:00 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=452</guid>
		<description><![CDATA[간혹 JavaScript같은 동적 타이핑 언어들이 타입을 명시하지 않아도 되기에, 타이핑을 절약해 생산성 향상을 도모할 수 있다는 글을 봅니다. 글쎄요, 아주 작은 규모의 프로그램이라면 모르겠지만, 규모가 조금만 커져도 이 말은 헛소리가 되고 맙니다. 이러한 형식 미지정 언어 기능은 타이핑 시간은 줄여주겠지만, 코드만으로 필요한 형식을 알 수 없게 되기에 타이핑이 끝난 그 순간부터 고통이 시작됩니다. 다음 코드를 보아 [...]]]></description>
			<content:encoded><![CDATA[<p>간혹 JavaScript같은 동적 타이핑 언어들이 타입을 명시하지 않아도 되기에, 타이핑을 절약해 생산성 향상을 도모할 수 있다는 글을 봅니다.</p>
<p>글쎄요, 아주 작은 규모의 프로그램이라면 모르겠지만, 규모가 조금만 커져도 이 말은 헛소리가 되고 맙니다. 이러한 형식 미지정 언어 기능은 타이핑 시간은 줄여주겠지만, 코드만으로 필요한 형식을 알 수 없게 되기에 타이핑이 끝난 그 순간부터 고통이 시작됩니다.</p>
<p>다음 코드를 보아 주세요.</p>
<blockquote>
<pre><code>var queryAboutSomething = function(server, dataToFill, optionByCustomer)
{
    //...
}</code></pre>
</blockquote>
<p>인수들이 어떤 타입이어야 하는지 알 수 있나요? 이 함수를 호출하기 위해서는 어떤 개체들을 준비해야 하나요? 제대로된 타입의 개체를 넣지 않으면 함수는 오류를 내고 뻗어버립니다. 아무거나 넣으면 알아서 처리해주는 매직 함수를 작성할 수도 있겠지만, 그러면 인수를 검사하는 코드가 본문보다 길어질 것입니다.</p>
<p>이 인수들의 타입을 알아내기 위해서는 함수 전체를 리뷰해야 합니다. 그래서 결국 타입 정보를 주석이나 문서에 써넣게 되는데, 이런 주석은 코드와 동기화되지 않은 가능성이 매우 높기에 &#8216;나쁜 주석&#8217;의 표본이 되며, 문서에 있다면 함수를 호출할때마다 문서를 뒤적여야 하기에 생산성은 극도로 떨어지게 됩니다. 형식을 지정하는 어떤 표준적인 방법 또한 없으므로 코드 편집 툴이 자동으로 형식을 알려줄 수 있는 방법 또한 없습니다. 컴파일러나 인터프리터가 인수의 형식을 검사해 잘못된 호출을 자동으로 방지할 수 있을만한 기능도 없습니다. 작성은 편하지만 호출할 때는 몇 배의 시간이 필요합니다. 모든 함수의 인수 형식들을 기억할 수 있는 천재적인 머리를 가지고 있다면 이야기가 좀 다르긴 합니다. 설마 헝가리안 표기법을 생각하고 있는 분은 없겠죠?</p>
<p>제가 보기엔 이런 식으로 형식 정보를 알 수 없는 언어들의 생산성은 기계어보다 나을 것이 없어보입니다.</p>
<p>OCaml 같은 암시적 정적 타이핑의 경우, 자동 완성 기능이 잘 갖춰진 편집기가 있다면 명시적 타이핑과 같은 효과를 누릴 수 있을 겁니다.</p>
<h1>생산성의 핵심</h1>
<p>생산성의 핵심은 코드를 on-the-fly로 작성할 수 있는지 여부에 달려 있습니다. 코드 작성중에 문서나 헤더, 또는 StackOverflow를 뒤적여야 한다면 이미 생산성은 바닥을 기고 있는 겁니다. 또한, 리팩토링도 중요합니다. 내가 만든 식별자의 이름을 원하는 때에 마음껏 바꿀 수 있다면 이름을 정하느라 고민하지 않고 아무거나 쓴 다음 조금씩 고쳐갈 수 있습니다.</p>
<p>가장 큰 도움이 되는 것은 에디터의 이름 자동 완성 기능입니다. 함수를 호출할 때 타입을 포함한 함수의 시그니쳐가 뜹니다. 이걸 한번 쓱 보고 필요한 개체들을 만들 수 있습니다. 자동 완성 기능은 아주 빠른 레퍼런스 문서의 역할을 합니다. Visual Studio는 이를 극으로 밀어붙여 인텔리센스는 시그니쳐 뿐 아니라 문서 대부분을 바로 보여줍니다. 또한 자동 완성 기능은 타이핑 오타도 없애줍니다. 타이핑하는 순간 자동 완성이 되지 않는다면 정의되지 않은 이름이란 것을 순간적으로 알 수 있습니다.</p>
<p>두번째는 코드가 얼마나 읽기 쉬우냐에 달려 있습니다. 디버깅이든 유지관리든 간에 코드는 한번만에 끝낼 수 없습니다. 어떤식으로든 꾸준한 리뷰가 필요합니다. 리뷰시 인수 검사와 같은 데코레이션 사이에 파묻혀 있는 로직을 찾아내야 한다면 역시 생산성이 추락하고 있는 겁니다. 그래서 코드는 가능한한 필요한 로직만 기술해야 합니다. 어떠한 비-로직 코드가 많이 필요하다면 별도의 메서드로 분리해 읽기 쉽게 만들어야 합니다.</p>
<p>세번째는 강력한 디버거입니다. 런타임에 작동하는 인터랙티브 콘솔이 주어진다면 더 좋겠죠. 물론 이 콘솔은 위에서 언급한 이름 제시 및 완성 기능을 완전히 지원해야 합니다. 만약 메모리 변화가 트랜젝션이 가능해서 이러한 콘솔로 작동한 부분을 롤백시킬 수 있다면 실시간으로 소스코드를 수정하는 것도 가능할 겁니다.</p>
<h1>동적 타이핑의 유용성</h1>
<p>하지만 동적 타이핑도 유용할 수 있습니다. 아주 작은 규모의 프로그램에서만 말이죠. 함수도 필요없이 단순히 순차적으로 실행되고 끝나는 진짜 &#8216;프로그램&#8217; 말이죠. HTML에서의 스크립트의 역할이 원래 그런 것이었기에 자바스크립트가 암시적 타이핑 언어가 되었을 겁니다. 함수를 정의하더라도 항상 코드 전체를 리뷰하기에 부담없는 사이즈였겠죠. 하지만 그 이상의 규모에서는 안됩니다. 함수같이 구조를 정의하려면 명시적 타이핑이 반드시 필요합니다. 물론 동적 타이핑보다는 OCaml같은 암시적 정적 타이핑이 훨씬 더 낫습니다.</p>
<p>이런 작은 규모에서 유용함을 지키려면 구조 작성 기능이 없어야 할겁니다. 있어도 최대한 사용을 절제해야겠죠.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/452/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>동적 언어의 태생적인 성능 한계</title>
		<link>http://blog.eonil.com/post/421</link>
		<comments>http://blog.eonil.com/post/421#comments</comments>
		<pubDate>Wed, 10 Feb 2010 12:48:13 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=421</guid>
		<description><![CDATA[동적 언어는 간단히 말하면 동적 분기를 지원하는 언어입니다. 여러가지 폼이 있지만, 핵심은 그 하나입니다. 그리고 이 동적 분기는 그 컨셉 자체가 CPU가 최적화하기 힘든 컨셉입니다. 그래서 동적 언어는 정적 언어에 비해 느릴 수 밖에 없게 됩니다.]]></description>
			<content:encoded><![CDATA[<p>동적 언어는 간단히 말하면 동적 분기를 지원하는 언어입니다. 여러가지 폼이 있지만, 핵심은 그 하나입니다. 그리고 이 동적 분기는 그 컨셉 자체가 CPU가 최적화하기 힘든 컨셉입니다. 그래서 동적 언어는 정적 언어에 비해 느릴 수 밖에 없게 됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/421/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>최적화 요약</title>
		<link>http://blog.eonil.com/post/414</link>
		<comments>http://blog.eonil.com/post/414#comments</comments>
		<pubDate>Wed, 10 Feb 2010 12:29:08 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[최적화]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=414</guid>
		<description><![CDATA[최적화에 대해 이런저런 말이 많지만 어려운 부분은 저로서는 감당하기 힘드네요. 개발시 간편하게 쓸 수 있는 최적화 기법만 정리해 봅니다. 하드웨어 활용 컴파일러 최적화 동적 분기 최소화 연산 결과 캐시 하드웨어 활용 첫째로 해야 하는 것이 하드웨어 활용입니다. 소프트웨어 레벨에서 아무리 뭘 하더라도 하드웨어를 따라갈 수는 없습니다. 단, 이것은 프로젝트 초기에 결정해야 합니다. 어떤 플랫폼과 프레임워크를 [...]]]></description>
			<content:encoded><![CDATA[<p>최적화에 대해 이런저런 말이 많지만 어려운 부분은 저로서는 감당하기 힘드네요.</p>
<p>개발시 간편하게 쓸 수 있는 최적화 기법만 정리해 봅니다.</p>
<ol>
<li>하드웨어 활용</li>
<li>컴파일러 최적화</li>
<li>동적 분기 최소화</li>
<li>연산 결과 캐시</li>
</ol>
<h1><span style="font-weight: normal">하드웨어 활용</span></h1>
<p>첫째로 해야 하는 것이 하드웨어 활용입니다. 소프트웨어 레벨에서 아무리 뭘 하더라도 하드웨어를 따라갈 수는 없습니다. 단, 이것은 프로젝트 초기에 결정해야 합니다. 어떤 플랫폼과 프레임워크를 쓰는지에 대한 문제이니까요.</p>
<p>일반적으로 특정 하드웨어에 종속적인 해결법은 하드웨어가 바뀜에 따라 무효해지므로, 구현비용을 잘 생각해서 결정해야 합니다. 간단히 구현할 수 있다면 조건부 컴파일로 쓸 수 있겠죠. 표준 스펙에 기반한 하드웨어 가속 기능을 사용하는 것이 가장 이상적입니다. 이런 관점에서 볼 때 크로노스 그룹의 오픈 표준 시리즈는 상당히 괜찮습니다.</p>
<p>만약 가상 하드웨어 샌드박스 플랫폼 안에 안에 있더라도 동일합니다. 이경우 일반적인 하드웨어와는 달리 종류를 막론하고 샌드박스 밖에서 바로 수입된 기능의 성능이 가장 좋겠죠.</p>
<h1><span style="font-weight: normal">컴파일러 최적화</span></h1>
<p>Code Complete 책에서도 현대 컴파일러 최적화는 너무 다양해 예측하기 힘드므로 프로파일링해야 한다고 나와 있습니다. 컴파일러 최적화는 제가 아는 한 가장 쉽습니다. 하나의 룰만 지키면 됩니다.</p>
<ul>
<li>수동 최적화하지 말 것</li>
</ul>
<p>일반적으로 수동 최적화는 컴파일러 최적화를 방해합니다. 컴파일러나 하드웨어에 대해 통달하지 않았다면 항상 컴파일러 최적화가 더 똑똑합니다. 수동 최적화된 코드는 특이하므로 컴파일러가 인지하기 어렵습니다. 현재 컴파일러들은 배열 언롤이나 함수 인라이닝은 물론, SIMD를 자동으로 활용하는 자동 벡터화 기능도 포함하고 있습니다. 각 하드웨어에 맞는 SIMD를 수동 작성하는것보다는 이쪽이 훨씬 낫겠죠.</p>
<h1><span style="font-weight: normal">동적 분기 최소화</span></h1>
<p>Dynamic Dispatch는 동적 언어의 핵심입니다. 언어가 유연할수록 느려질 수 밖에 없는 이유가 바로 이것입니다. 유연성의 핵심은 분기가 얼마나 자유로우냐인데, 자유로운 분기는 CPU상에서 실행시 최적화되기 힘드므로 빨라질 수 없습니다. 가상 함수 계열은 모두 동적 분기이므로 이를 줄이면 큰 성능 향상을 가져올 수 있습니다. 그래서 이러한 가상 함수를 지원하는 언어는 대개 가상 함수를 finalize 해 성능을 높이는 키워드를 지원합니다. 보통은 final 키워드이죠. 함수명에 사용해 함수의 오버라이드를 금지시키거나, 클래스명에 사용해 모든 멤버의 오버라이딩을 한번에 봉쇄하기도 하죠.</p>
<p>Objective-C의 메시징 메커니즘은 기본적으로 동적 분기입니다. 여기에는 final 같은 키워드도 없으니 분기 예측을 통한 실행 성능 형상은 기대할 수 없습니다. 그러므로 성능이 중요한 코드는 Objective-C로 작성해서는 안되며, C로 작성되어야 합니다. 하지만 보통 어플리케이션 로직과 UI는 성능보다 유연성을 필요로 하므로 Cocoa의 역할은 알맞다고 할 수 있습니다.</p>
<h1><span style="font-weight: normal">연산 결과 캐시</span></h1>
<p>사실상 프로그래머가 로직으로 간단히 할 수 있는 유일한 최적화 기법이라 할 수 있습니다. 대부분의 경우 소개되는 최적화 기법은</p>
<ol>
<li>컴파일러 최적화를 방해하거나</li>
<li>캐시하거나</li>
</ol>
<p>둘 중에 하나입니다. 캐시는 일종의 연산 제거입니다. 동일한 연산의 불필요한 중복 수행을 방지하는 컨셉이죠. 단점이라면 메모리가 필요하다는 것입니다. 제 생각에는 일반적인 프로그래머의 입장에서 캐시 외에는 답이 없다고 봅니다. 하드웨어에 밀접하고 컴파일러가 최적화를 잘 못해준다면 이야기가 좀 다르겠지만요.</p>
<p>캐시를 잘 작성하기 위한 방법은 한 가지입니다.</p>
<ul>
<li>최적화하지 말것. 느리다면 그 때 프로파일링하고 병목을 제거할 것.</li>
</ul>
<p>맥코넬씨가 강조하는 핵심이죠. 일단 프로그램 작성시에는 효율을 생각하지 않고, 로직과 구조에만 집중해서 제작합니다. 예를 들면:</p>
<p>데이터가 필요하다면 그때그때 파일을 열어 DB에서 읽어옵니다.</p>
<ol>
<li>이게 느리면 파일 핸들을 캐시하고,</li>
<li>그래도 느리면, DB 연결도 캐시하고,</li>
<li>그래도 느리면 쿼리 결과도 캐시합니다.</li>
<li>그래도 느리다면 결과셋이 표시된 UI도 캐시해야겠죠.</li>
</ol>
<p>DB 내에도 일종의 캐시 구조가 있을 것입니다. 인덱스라는 기능이 있죠. 미리 계산된 데이터 위치를 따로 저장하는 것입니다. 캐시는 메모리와 프로세싱 사이에서 트레이드 오프가 가능하므로, 전체적인 시스템 사양에 따라 동적으로 조절될 수도 있습니다. 하지만 무엇보다도 만들기 쉽다는 것이 장점입니다. 전체 시스템 구조를 변경하지 않고 캐시를 추가하는 것은 어렵지 않습니다.*</p>
<p>*최근에 생각이 바뀌었습니다. 캐시같은 최적화는 로직을 변경하는 것이고, 필요에 따라서 최적화되지 않은 일명 &#8220;기준 로직 코드&#8221;로의 스위칭이 가능해야 할 것을 요구받습니다. 그래서 최적화를 해야 할 코드는 반드시 별도로 분리시켜 추상화해야 합니다. 결국, 최적화에는 필수적으로 리팩터링이 수반됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/414/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>정점 데이터 사용법</title>
		<link>http://blog.eonil.com/post/405</link>
		<comments>http://blog.eonil.com/post/405#comments</comments>
		<pubDate>Fri, 05 Feb 2010 18:49:16 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development/GL]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/archive/2010/02/06/%ec%a0%95%ec%a0%90-%eb%8d%b0%ec%9d%b4%ed%84%b0-%ec%82%ac%ec%9a%a9%eb%b2%95/</guid>
		<description><![CDATA[GLES에서 그려질 정점 데이터를 전송하는 방법은 두가지가 있습니다. 직접 전송 버퍼로 캐시 1. 직접 전송 기본 방식입니다. 정점을 GPU로 바로 전송해 그리도록 합니다. 매번 그릴 때마다 정점이 전송되므로 VRAM이 필요없는 대신, 전송 대역이 필요합니다. 정점이 매우 많이 필요한 데이터가 아니라면, 대역이 많이 필요하지 않으므로 VRAM을 아끼기 위해서도 좋은 방법일 수 있습니다. 또한, 매번 정점 데이터를 [...]]]></description>
			<content:encoded><![CDATA[<p>GLES에서 그려질 정점 데이터를 전송하는 방법은 두가지가 있습니다.</p>
<ol>
<li>직접 전송</li>
<li>버퍼로 캐시</li>
</ol>
<h1>1. 직접 전송</h1>
<p>기본 방식입니다.<br />
정점을 GPU로 바로 전송해 그리도록 합니다. 매번 그릴 때마다 정점이 전송되므로 VRAM이 필요없는 대신, 전송 대역이 필요합니다.<br />
정점이 매우 많이 필요한 데이터가 아니라면, 대역이 많이 필요하지 않으므로 VRAM을 아끼기 위해서도 좋은 방법일 수 있습니다. 또한, 매번 정점 데이터를 보낼 때마다 갱신할 수도 있기에 동적인 정점이 필요하다면 이쪽이 더 좋습니다.</p>
<h1>2. 버퍼로 캐시</h1>
<p>정점이 많아지면 전송 대역에 한계가 오고 성능 저하로 이어집니다. 이에 정점을 VRAM에 캐시하고 이를 사용하도록 하는 방법입니다. 이 캐시를 VBO(Vertex Buffer Object)라 하며, DirectX의 VertexBuffer의 역할을 합니다.</p>
<ul>
<li>그리기 전, 정점을 미리 보내 두어야 합니다.</li>
<li>VRAM이 필요하며,</li>
<li>드로잉 시에는 대역을 아낄 수 있습니다.</li>
<li>정점이 많이 필요할 경우 좋습니다.</li>
</ul>
<p>정점을 수정해야 할 경우, 새로 보내야 하므로 버퍼로 인한 이득이 사라집니다. 그래서 고정된 정점에만 사용해야 합니다.</p>
<h1>버텍스 셰이더</h1>
<p>그래픽 피델리티가 올라가면서 대량의 정점을 사용하는 것이 불가피하기에 버퍼를 쓸 수 밖에 없는데, 버퍼(=VRAM)에 있는 정점은 CPU가 엑세스할 수 없기에 동적인 변화를 줄 수 없습니다. 그래서 GPU가 버퍼에 있는 정점을 동적으로 사용할 수 있도록 하는 방법을 찾게 됩니다. 이것이 정점 프로그램, 즉 버텍스 셰이더입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/405/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objective-C++</title>
		<link>http://blog.eonil.com/post/398</link>
		<comments>http://blog.eonil.com/post/398#comments</comments>
		<pubDate>Mon, 01 Feb 2010 21:48:40 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>
		<category><![CDATA[objective-c++]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=398</guid>
		<description><![CDATA[Objective-C는 C 기반 언어이므로 C는 자연스럽게 섞어쓸 수 있습니다. C에 존재하는  기능은 아예 있지도 않을 정도니까요. (예: 정적 필드) 하지만 C++는 이와 비슷하게 C에서 갈라져 나온 언어로 Objective-C와는 다른 길을 걷어왔습니다. 이들은 기본적으로 호환이 되지 않습니다. 하지만 이들은 결국 C의 확장이므로, 포인터와 기본형식, 함수 호출이라는 최소의 공통분모가 있습니다. 기를 기반으로 애플은 이들을 섞어쓸 수 있도록 [...]]]></description>
			<content:encoded><![CDATA[<p>Objective-C는 C 기반 언어이므로 C는 자연스럽게 섞어쓸 수 있습니다. C에 존재하는  기능은 아예 있지도 않을 정도니까요. (예: 정적 필드)</p>
<p>하지만 C++는 이와 비슷하게 C에서 갈라져 나온 언어로 Objective-C와는 다른 길을 걷어왔습니다. 이들은 기본적으로 호환이 되지 않습니다. 하지만 이들은 결국 C의 확장이므로, 포인터와 기본형식, 함수 호출이라는 최소의 공통분모가 있습니다. 기를 기반으로 애플은 이들을 섞어쓸 수 있도록 하는 옵션을 주었고, 실제로는 이들을 섞어서 사용할 수 있습니다. 여기에서 가장 기반이 되는 것은 포인터=개체라는 룰입니다. 하지만 제약이 있습니다.</p>
<ul>
<li>별도의 처리가 필요하므로 컴파일러가 이를 인지할 수 있도록 소스파일 확장자를 <code>.mm</code>으로 주어야 합니다.</li>
<li>타입 시스템이 호환되지 않습니다. 그래서 클래스 정의와 상속은 완전히 분리되어 섞을 수 없습니다.</li>
<li>C++ 키워드는 인스턴스 변수 식별자로 사용할 수 없습니다. 다른 컨텍스트에서는 허용됩니다.</li>
<li><code>id</code>라는 이름의 C++ 템플릿을 만들 수 없습니다. Objective-C의 프로토콜 정의와 문법이 겹치기 때문입니다.</li>
<li>예외 처리가 분리됩니다. C++예외는 C++코드에서만, Objective-C 예외는 Objective-C 코드에서만  캐치할 수 있습니다.</li>
<li>Objective-C의 클래스 안에 C++클래스를 정의해도 전역 클래스로 간주됩니다.</li>
</ul>
<p>더 자세한 내용은 레퍼런스 페이지에서 확인하실 수 있습니다:<br />
<a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html#//apple_ref/doc/uid/TP30001163-CH10-SW1">http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html#//apple_ref/doc/uid/TP30001163-CH10-SW1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/398/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>코코아 터치에서 간단한 로컬 데이터 다루기</title>
		<link>http://blog.eonil.com/post/395</link>
		<comments>http://blog.eonil.com/post/395#comments</comments>
		<pubDate>Sat, 23 Jan 2010 14:13:05 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>
		<category><![CDATA[cocoa touch]]></category>
		<category><![CDATA[property list]]></category>
		<category><![CDATA[데이터]]></category>
		<category><![CDATA[프로퍼티 리스트]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=395</guid>
		<description><![CDATA[플래시에는 e4x가 있습니다. 그래서 웬만한 데이터는 전부 XML로 만들어서 처리해 버립니다. 플래시에서 XML을 주로 사용하는 이유는 e4x라는 강력한 도구 때문이며, XML 자체의 특징이나 매력과는 큰 상관이 없습니다. 그러면, 코코아 터치에서는 무엇으로 데이터를 다루나요? 결론부터 말씀드리자면 Property List입니다. 이것은 일종의 규격화된 XML로, 작은 데이터를 다루기에 알맞습니다. 데이터셋 크기가 커지면 다소 비효율적이라 예상합니다. 이 프로퍼티 리스트는 기본 [...]]]></description>
			<content:encoded><![CDATA[<p>플래시에는 e4x가 있습니다. 그래서 웬만한 데이터는 전부 XML로 만들어서 처리해 버립니다. 플래시에서 XML을 주로 사용하는 이유는 e4x라는 강력한 도구 때문이며, XML 자체의 특징이나 매력과는 큰 상관이 없습니다.</p>
<blockquote><p>그러면, 코코아 터치에서는 무엇으로 데이터를 다루나요?</p></blockquote>
<p>결론부터 말씀드리자면 Property List입니다. 이것은 일종의 규격화된 XML로, 작은 데이터를 다루기에 알맞습니다. 데이터셋 크기가 커지면 다소 비효율적이라 예상합니다. 이 프로퍼티 리스트는 기본 컬렉션 개체인 NSArray와 NSDictionary에서 직접 지원하며, 정수, 문자열 등의 기본적인 프리미티브 형식 몇 가지를 지원합니다. 또한 계층적 개체로 구조화된 데이터도 저장할 수 있습니다. 설정 파일이나 그 외 간단한 용도로 제격이죠. XML로 저장되지만, 기능이나 사용 형태는 JSON에 가깝습니다. 예를 들어 전체 데이터셋을 로드하기 위해서 다음 중 하나의 메서드를 사용하면 됩니다.</p>
<blockquote>
<pre><code>[NSArray arrayWithContentsOfFile:]
[NSDictionary dictionaryWithContentsOfFile:]</code></pre>
</blockquote>
<p>사실 <del datetime="2010-12-08T03:48:31+00:00">정수, 실수,</del> 문자열과 단순 목록, 연관 목록을 지원하면 모든 종류의 데이터를 다 담을 수 있습니다. 데이터베이스란 것도 사실 별 거 없죠. 하지만 프로퍼티 리스트의 존재를 알기까지는 생각보다 힘든 과정이 필요했습니다.</p>
<h1>혼란</h1>
<p>처음에 필요했던 것은 간단한 로컬 데이터를 목록으로 만들어 읽는 것이었습니다. 하지만 이런 일이 자주 발생될 것이 너무 뻔하게 예상되므로 기왕이면 플래시의 e4x처럼 프레임워크가 자연스럽게 지원하는 가장 간편한 방식을 알아내고 싶었습니다. 또한, 웹상에 존재하는 많은 종류의 공개 API는 대부분 XML을 기본 데이터 형식으로 사용합니다. 그리고, 이러한 데이터는 프로그래머만 다루는 것이 아니며 때때로 기획자나 디자이너도 다룰 수 있게 해야 합니다. 이런 것을 종합하면, XML외에는 대안이 없습니다. XML도 어려워하는 사람이 많지만, 그나마 가장 널리 퍼져 있는 것이 XML이기 때문입니다. 타 직업군의 사람과의 호환성 확보에 가장 좋다고 할 수 있죠. 결국 제가 원한 프레임워크는 언어 내에서 간단히 다를 수 있으면서도 XML로 읽고 쓸 수 있는 프레임워크였죠. 일단 XML 지원은 필수였습니다.</p>
<h1>코어 데이터</h1>
<p>처음에 접한 것은 코어 데이터였습니다. 코어 데이터는 대량의 데이터셋을 위해 최적화된 데이터 엑세스 프레임워크입니다. SQLite DB나 바이너리 또는 XML을 백엔드 저장소로 사용할 수 있습니다. 개별 개체의 데이터 변화를 모두 추적하고, 컨트롤에 자동 바인딩도 지원합니다. 네트워크와는 크게 상관없어 보이지만, 어딘가 그런 기능이 있을지도 모릅니다. 애플에서 권장하는 데이터 엑세스 방식이죠. 일견 기능은 매우 강력해 보이지만, 헛점이 있습니다. 너무 어렵다는 것입니다.</p>
<p>코어 데이터를 다루기 위해서는 기본적으로 코코아 바인딩을 마스터해야 합니다. 그런데 이 코코아 바인딩이란 놈이 만만치 않죠. 그 외에도 몇 가지의 복잡한 개념을 이해해야 합니다. 사실 이 기술들의 컨셉은 별 거 없지만, 애플 엔지니어들에게 딱 맞춰진 개념 구현을 익혀야 한다는게 정말 어렵습니다. 그리고 이런 종류의 데이터 바인딩 프레임워크가 다 그렇듯, 유연성이 떨어져 실제 사용에는 제약이 많습니다. 바인딩은 정말 폼 기반 어플리케이션같은 특정 목적의 응용이 아니면 적합하지 않습니다.</p>
<p>그러면 코어 데이터에서 남는 것은 대량의 데이터셋을 효과적으로 다룰 수 있는 아키텍쳐 뿐입니다. 하지만 이것은 데이터가 로컬에 있을 때에나 해당하는 것이며, 데이터가 원격 서버에 있다면 데이터셋 스쿠핑은 서버에서 해결하므로 사실 큰 의미가 없습니다.</p>
<p>XML지원도 사실 어떤 식으로 되는지 모릅니다. 샘플을 슬쩍 봤는데, 개별 개체를 인코딩하고 계층 구조는 개체 아이디로 레퍼런싱하는 방식을 사용하는 듯 했습니다. 이런건 프로그래머도 못봅니다. 오로지 기계만 읽을 수 있습니다.</p>
<p>결국 뭔가 강력한 기능을 제공한다는 것은 알겠지만, 아직 저는 정말로 필요한 때가 아닌 것 같습니다.</p>
<h1>아카이브</h1>
<p>아카이브는 개체를 바이너리로 저장하는 기능입니다. 코어 데이터의 주 구성 요소 기술 중 하나이죠. 이건 말 그대로 바이너리입니다. 이걸로 커스텀 데이터셋을 간편히 만든다는 것 자체가 불가능하고, XML과도 관련이 없습니다. 그래서 패스했습니다.</p>
<h1>JSON</h1>
<p>애플 푸시 서비스의 샘플이 JSON으로 되어 있어서 JSON에 관심을 가져 보았으나, 제조사인 애플에서 제공하는 기반 프레임워크가 없는데다, 사용되는 분야가 너무 한정적이라 그만두었습니다. 그리고 웹에서 필수적으로 발생하는 인코딩과 이스케이프 문제에 대한 정의가 너무 허술한 듯 했습니다. 특히 언어에 종속된 문법으로 인해 슬래시를 모두 이스케이프해야 한다는 것은 치명적입니다.</p>
<p>간략한 데이터셋은 프로그래머만 사용하는 것이 아닙니다. 때로는 디자이너나 기획자에게 전달하고, 그들에게 내용을 받아와야 하는 때도 있습니다. 자기 스스로 데이터를 편집하기를 윈하지만, 어려운 것은 다루지 못하는 사람들이 많죠. 여기에 <code>http://</code>로 시작하는 링크조차 모두 이스케이프해야 하는 JSON은 적용하기 힘듭니다.</p>
<h1>NSXMLParser</h1>
<p>코코아 터치에서 정말깜짝 놀란 것이 XML DOM 파서가 없다는 것이었습니다. 대신 이벤트 드리븐 파서를 제공하는데, 말이 파서지 사실 쓸게 못됩니다. 스트림 프로세서를 만드는 것 외에는 쓸 수 있는 곳이 거의 없고, 결국엔 이 파서를 이용해 작은 전용 DOM 을 만드는 식으로 일이 진행됩니다. 처음에는 <code>forwardInvocation</code> 기능을 이용해 e4x처럼 동적으로 개별 노드에 엑세스하는 DOM 개체를 만들려 했습니다. 그런데 Objective-C 컴파일러는 선언되지 않은 셀렉터에 대해 경고를 내보냅니다. 경고를 무시하는 것은 잠재적인 위험을 무시하는 것이므로, 결국 이 방식을 쓰지 못하게 되었습니다.</p>
<p>이 작은 DOM은 매우 작은 커스텀 XML 메시지를 만들기에 적합하므로 XML API를 사용할 때 유용하리라 생각해서 없애지는 않았습니다만, 기본 데이터 엑세스 용도로는 사용하지 않습니다. 프로퍼티 리스트를 발견했기 때문이죠.</p>
<h1><code>NSArray</code>/<code>NSDictionary</code> 그리고 프로퍼티 리스트</h1>
<p>모든 것을 다 포기하고, 기본적인 배열과 사전 개체로 해결을 보려 했습니다. <code>NSArray</code>의 오토릴리즈된 생성자 목록을 보던 중a<code>rrayWithContentsOfFile</code>이라는 메서드가 보이더군요. 순간 감이 왔습니다. 애플 엔지니어가 이런것을 생각하지 않았을리 없죠. 미리 다 준비해뒀을 건데 왜 안보이는 걸까. 그건 그게 너무 가까이 있어서 보지 못했기 때문이 아닐까? 하는 생각이 들었죠. 바로 레퍼런스를 뒤적였고, 이 메서드의 설명 근처에서 Property List라는 키워드를 찾을 수 있었습니다. 사실 프로퍼티 리스트는 전부터 알고 있었는데 잊어버리고 있었습니다. e4x의 기능을 가진 프레임워크를 찾는 데 너무 집착했기 때문이죠. 프로퍼티 리스트를 구성 설정에 주로 쓰이며, 간략한 데이터셋을 다루는데 최적입니다. 이제 모든 문제를 해결했습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/395/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>맥의 키보드 키 기호를 이미지가 아닌 글자로 입력하는 방법</title>
		<link>http://blog.eonil.com/post/391</link>
		<comments>http://blog.eonil.com/post/391#comments</comments>
		<pubDate>Sun, 10 Jan 2010 20:53:10 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/archive/2010/01/11/%eb%a7%a5%ec%9d%98-%ed%82%a4%eb%b3%b4%eb%93%9c-%ed%82%a4-%ea%b8%b0%ed%98%b8%eb%a5%bc-%ec%9d%b4%eb%af%b8%ec%a7%80%ea%b0%80-%ec%95%84%eb%8b%8c-%ea%b8%80%ec%9e%90%eb%a1%9c-%ec%9e%85%eb%a0%a5%ed%95%98/</guid>
		<description><![CDATA[맥의 키보드 키 기호를 이미지가 아닌 글자로 입력하는 방법입니다. http://macbiblioblog.blogspot.com/2005/05/special-key-symbols.html]]></description>
			<content:encoded><![CDATA[<p>맥의 키보드 키 기호를 이미지가 아닌 글자로 입력하는 방법입니다.</p>
<p><a href="http://macbiblioblog.blogspot.com/2005/05/special-key-symbols.html">http://macbiblioblog.blogspot.com/2005/05/special-key-symbols.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/391/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode 팁&amp;트릭</title>
		<link>http://blog.eonil.com/post/385</link>
		<comments>http://blog.eonil.com/post/385#comments</comments>
		<pubDate>Sun, 10 Jan 2010 20:43:34 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=385</guid>
		<description><![CDATA[Xcode 틱 트릭]]></description>
			<content:encoded><![CDATA[<p>전에 Xcode의 <a href="http://blog.eonil.com/archive/2010/01/11/xcode-팁트릭/">단축키 목록을 링크</a>했었는데요, 스택오버플로우에서 누가 Xcode의 틱&amp;트릭에 대해서 질문했습니다:<br />
<a href="http://stackoverflow.com/questions/146297/what-are-those-little-xcode-tips-tricks-you-wish-you-knew-about-2-years-ago">http://stackoverflow.com/questions/146297/what-are-those-little-xcode-tips-tricks-you-wish-you-knew-about-2-years-ago</a></p>
<p>유용한 기능이 많아서 따로 모아봤습니다. 제가 알아낸 기능도 포함했습니다.</p>
<h2>목록</h2>
<ul>
<li>에디터에서 <code>.h</code>와 <code>.m</code> 파일 전환(토글)<br />
⌘⌥⇡</li>
<li>편집 위치 히스토리 전환<br />
⌘⌥⇠<br />
⌘⌥⇢</li>
<li>정의로 이동(Jump to Definition), 인터페이스 빌더에서 소스코드로 이동도 가능<br />
⌘ double-click</li>
<li>레퍼런스 문서의 심볼 도움말로 이동 (기본 문서에만 적용)<br />
⌘⇧D<br />
⌥ double-click</li>
<li>코드창 확장/축소 토글<br />
⌘⇧E</li>
<li>코드 컴플리션 (각각 범위가 다름)<br />
Esc<br />
Tab</li>
<li>파일/멤버/심볼 등의 목록 팝업<br />
⌃1<br />
⌃2<br />
⌃3</li>
<li>주석 표시 (멤버 목록에 하이라이트됨)<br />
// TODO:<br />
// FIXME:<br />
// !!!:<br />
// ???:</li>
<li>코드창 나누기 버튼을 클릭할 때 옵션을 누르고 있으면 가로로 나눠짐<br />
⌥ click</li>
<li>선택한 텍스트 영역의 탭 인덴트/언인덴트<br />
⌘[<br />
⌘]</li>
<li>간결한 클래스 정의 명세 및 헬프 브라우저<br />
Project &gt; Class Browser<br />
⌘⇧C</li>
</ul>
<h2>부록</h2>
<p>읽는 법입니다:<br />
<a href="http://support.apple.com/kb/HT1343">http://support.apple.com/kb/HT1343</a></p>
<ul>
<li>⌘ (Command key) &#8211; Sometimes called &#8220;Apple key&#8221;()</li>
<li>⌃ (Control key)</li>
<li>⌥ (Option key) &#8211; &#8220;Alt&#8221; may also appear on this key</li>
<li>⇧ (Shift key)</li>
<li>⇪ (Caps Lock)</li>
<li>fn (Function key)</li>
</ul>
<p>추가:<br />
<a href="http://blog.eonil.com/archive/2010/01/11/맥의-키보드-키-기호를-이미지가-아닌-글자로-입력하/">http://blog.eonil.com/archive/2010/01/11/맥의-키보드-키-기호를-이미지가-아닌-글자로-입력하/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/385/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objective-C/Cocoa에서 개체 비교</title>
		<link>http://blog.eonil.com/post/364</link>
		<comments>http://blog.eonil.com/post/364#comments</comments>
		<pubDate>Wed, 06 Jan 2010 14:56:33 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=364</guid>
		<description><![CDATA[개체의 동일성 비교는 언어의 중요한 요소입니다. Objective-C(이하 objc)는 기본적으로 C이기 때문에 비교 연산자는 수치 비교를 합니다. 따라서 포인터의 경우, 포인터 값 비교가 되므로, 개체 참조 비교가 됩니다. 하지만 OO개념에 따라, 동일성의 의미가 개체에 따라 달라질 수 있어야 하므로, 코코아에서는 프로토콜로 동일성 비교 기능을 제공하고 프레임워크 전체적으로 이 기능을 사용해 개체 스스로 동일성 비교를 수행할 수 [...]]]></description>
			<content:encoded><![CDATA[<p>개체의 동일성 비교는 언어의 중요한 요소입니다. Objective-C(이하 objc)는 기본적으로 C이기 때문에 비교 연산자는 수치 비교를 합니다. 따라서 포인터의 경우, 포인터 값 비교가 되므로, 개체 참조 비교가 됩니다.</p>
<p>하지만 OO개념에 따라, 동일성의 의미가 개체에 따라 달라질 수 있어야 하므로, 코코아에서는 프로토콜로 동일성 비교 기능을 제공하고 프레임워크 전체적으로 이 기능을 사용해 개체 스스로 동일성 비교를 수행할 수 있게 합니다. 이 기능은 <code>isEqual</code> 메서드로 제공되는데, 문서를 보면 <code>isEqualTo</code>라는 메서드도 있습니다. 둘의 차이는 무엇일까요?</p>
<p><a href="http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg18003.html">http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg18003.html</a></p>
<p>켄씨에 따르면, <code>isEqual</code>이 기본적으로 제공되는 의미상 개체 비교 기능이고, <code>isEqualTo</code>는 스크립팅 지원을 위한 것이라고 합니다. 스크립트용으로 별도의 의미상 비교를 수행할 수 있도록 말이죠.</p>
<p>두 메서드 다 기본적으로는 수치(포인터) 비교를 사용하나, 필요에 따라 오버라이드 할 수 있습니다. 코코아는 프레임워크 전반적인 비교 루틴에 이들을 사용하므로, 쉽게 의미상 비교를 오버라이드할 수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/364/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ScrollView 안에 다른 뷰 요소 넣기</title>
		<link>http://blog.eonil.com/post/361</link>
		<comments>http://blog.eonil.com/post/361#comments</comments>
		<pubDate>Tue, 05 Jan 2010 21:16:22 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=361</guid>
		<description><![CDATA[이유는 알 수 없지만, ScrollView 안에는 기본적으로 CustomView가 들어 있으며, 이 커스텀뷰를 제거하거나 바꿀 수 없습니다. 스클로뷰 안에 다른 컨트롤을 넣으려면 메뉴에서 Layout &#62; Embeds Objects In &#62; &#8230; 을 사용해야 합니다. http://cocoadev.tistory.com/12 참고로 현재 사용환경은 Snow Leopard 10.6의 Xcode 3.2.1입니다.]]></description>
			<content:encoded><![CDATA[<p>이유는 알 수 없지만, ScrollView 안에는 기본적으로 CustomView가 들어 있으며, 이 커스텀뷰를 제거하거나 바꿀 수 없습니다. 스클로뷰 안에 다른 컨트롤을 넣으려면 메뉴에서 Layout &gt; Embeds Objects In &gt; &#8230; 을 사용해야 합니다.</p>
<p><a href="http://cocoadev.tistory.com/12">http://cocoadev.tistory.com/12</a></p>
<p>참고로 현재 사용환경은 Snow Leopard 10.6의 Xcode 3.2.1입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/361/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa 주요 이벤트 핸들링</title>
		<link>http://blog.eonil.com/post/340</link>
		<comments>http://blog.eonil.com/post/340#comments</comments>
		<pubDate>Mon, 04 Jan 2010 12:34:49 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=340</guid>
		<description><![CDATA[개체 생성 개체 생성은 [[NSObject alloc] init] 패턴을 사용합니다. alloc 메서드는 메모리를 할당하고, 초기화는 init... 메서드가 담당합니다. &#8216;생성자&#8217; 역할은 init... 메서드가 담당하죠. 그래서 커스텀 초기화를 수행하려면 init... 메서드를 오버라이드해 사용합니다. init... 메서드는 기본적인 사용 패턴이 있으면 그 패턴은 다음과 같습니다. - (id) init { self = [super init] if(self!=nil) { // Do something here. } return [...]]]></description>
			<content:encoded><![CDATA[<h2>개체 생성</h2>
<p>개체 생성은 <code>[[NSObject alloc] init]</code> 패턴을 사용합니다. <code>alloc</code> 메서드는 메모리를 할당하고, 초기화는 <code>init...</code> 메서드가 담당합니다. &#8216;생성자&#8217; 역할은 <code>init...</code> 메서드가 담당하죠.</p>
<p>그래서 커스텀 초기화를 수행하려면 <code>init...</code> 메서드를 오버라이드해 사용합니다. <code>init...</code> 메서드는 기본적인 사용 패턴이 있으면 그 패턴은 다음과 같습니다.</p>
<blockquote>
<pre><code>- (id) init
{
	self = [super init]
	if(self!=nil)
	{
		// Do something here.
	}
	return self;
}</code></pre>
</blockquote>
<h2>개체 소멸</h2>
<p>개체 소멸 시점에 처리해야 할 일이 있다면 <code>dealloc</code> 메서드를 오버라이드하면 됩니다. <code>dealloc</code> 의 사용 패턴은 다음과 같습니다.</p>
<blockquote>
<pre><code>- (void) dealloc
{
	// Do something here.
	[super dealloc];
}</code></pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/340/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C 포인터 간단 요약</title>
		<link>http://blog.eonil.com/post/334</link>
		<comments>http://blog.eonil.com/post/334#comments</comments>
		<pubDate>Mon, 04 Jan 2010 11:52:23 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=334</guid>
		<description><![CDATA[Meanings * = pointer to / value of. &#38; = address of. Usage // Declares &#8216;a&#8217; as integer, and sets 1. // Declares &#8216;b&#8217; as pointer to an integer, and sets address of &#8216;a&#8217;. // Declares &#8216;c&#8217; as integer, and sets value of &#8216;b&#8217;. // Returns equality of &#8216;a&#8217; and &#8216;c&#8217;. This is true. int [...]]]></description>
			<content:encoded><![CDATA[<h2>Meanings</h2>
<p><code>*</code> = pointer to / value of.</p>
<p><code>&amp;</code> = address of.</p>
<h2>Usage</h2>
<p>// Declares &#8216;a&#8217; as integer, and sets 1.<br />
// Declares &#8216;b&#8217; as <strong>pointer to</strong> an integer, and sets <strong>address of</strong> &#8216;a&#8217;.<br />
// Declares &#8216;c&#8217; as integer, and sets <strong>value of</strong> &#8216;b&#8217;.<br />
// Returns equality of &#8216;a&#8217; and &#8216;c&#8217;. This is true.</p>
<blockquote>
<pre><code>int a = 1;
int* b = &amp;a;
int c = *b;
return a==c; // Returns true.</code></pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/334/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode 단축키 목록</title>
		<link>http://blog.eonil.com/post/331</link>
		<comments>http://blog.eonil.com/post/331#comments</comments>
		<pubDate>Mon, 04 Jan 2010 10:41:38 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=331</guid>
		<description><![CDATA[Xcode 단축키 목록입니다: http://www.1729.us/xcode/Xcode%20Shortcuts.pdf]]></description>
			<content:encoded><![CDATA[<p>Xcode 단축키 목록입니다:</p>
<p><a href="http://www.1729.us/xcode/Xcode%20Shortcuts.pdf">http://www.1729.us/xcode/Xcode%20Shortcuts.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/331/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NSArray 특성</title>
		<link>http://blog.eonil.com/post/327</link>
		<comments>http://blog.eonil.com/post/327#comments</comments>
		<pubDate>Mon, 04 Jan 2010 10:33:43 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Cocoa]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=327</guid>
		<description><![CDATA[다음 글에 따르면 C 배열과는 달리 NSArray 에는 기본형식(int 등) 값을 저장할 수 없다는군요. 대신 NSNumber로 박싱하는 방식으로 사용한다고 합니다. 이 말이 사실이라면 기본형의 사용은최대한 피해야겠습니다. http://lists.apple.com/archives/Cocoa-dev/2003/Dec/msg01222.html 하지만 이 글은 2003년 글이므로 현재는 맞지 않을 수 있습니다.]]></description>
			<content:encoded><![CDATA[<p>다음 글에 따르면 C 배열과는 달리 <code>NSArray</code> 에는 기본형식(<code>int</code> 등) 값을 저장할 수 없다는군요. 대신 <code>NSNumber</code>로 박싱하는 방식으로 사용한다고 합니다. 이 말이 사실이라면 기본형의 사용은최대한 피해야겠습니다.</p>
<p><a href="http://lists.apple.com/archives/Cocoa-dev/2003/Dec/msg01222.html">http://lists.apple.com/archives/Cocoa-dev/2003/Dec/msg01222.html</a></p>
<p>하지만 이 글은 2003년 글이므로 현재는 맞지 않을 수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/327/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C 배열과 NSArray 성능 비교</title>
		<link>http://blog.eonil.com/post/321</link>
		<comments>http://blog.eonil.com/post/321#comments</comments>
		<pubDate>Mon, 04 Jan 2010 10:10:29 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=321</guid>
		<description><![CDATA[다음 링크는 C 기본 배열과 NSArray의 성능 비교입니다. http://memo.tv/nsarray_vs_c_array_performance_comparison http://memo.tv/nsarray_vs_c_array_performance_comparison_part_ii_makeobjectsperformselector NSArray가 여러가지 편리한 기능과 환경을 제공하지만, 성능만큼은 C 기본 배열을 따라갈 수 없습니다. 테스트 범위 내에서 100배~500배의 성능 차이가 보이네요. 이 테스트 결과만을 보면 C 배열이 매우 우월해 보이지만, 사실은 그렇지 않습니다. 두번째 포스팅의 답글 중, 이 내용에 대한 반박이 있습니다. 이 포스팅은 오래된 것이라 [...]]]></description>
			<content:encoded><![CDATA[<p>다음 링크는 C 기본 배열과 <code>NSArray</code>의 성능 비교입니다.</p>
<p><a href="http://memo.tv/nsarray_vs_c_array_performance_comparison">http://memo.tv/nsarray_vs_c_array_performance_comparison</a></p>
<p><a href="http://memo.tv/nsarray_vs_c_array_performance_comparison_part_ii_makeobjectsperformselector">http://memo.tv/nsarray_vs_c_array_performance_comparison_part_ii_makeobjectsperformselector</a></p>
<p><code>NSArray</code>가 여러가지 편리한 기능과 환경을 제공하지만, 성능만큼은 C 기본 배열을 따라갈 수 없습니다. 테스트 범위 내에서 100배~500배의 성능 차이가 보이네요.</p>
<p>이 테스트 결과만을 보면 C 배열이 매우 우월해 보이지만, 사실은 그렇지 않습니다. 두번째 포스팅의 답글 중, 이 내용에 대한 반박이 있습니다. 이 포스팅은 오래된 것이라 예전에는 맞을지 몰라도 지금은 그렇지 않다는군요. 그리고 이 비교는 순수한 이터레이션 성능만을 논하고 있는데, 실제 병목은 이터레이션 자체보다 이터레이션간 수행하는 작업에 의해 좌우되므로 이 테스트가 큰 의미가 없다는 뜻입니다.</p>
<p>또한, 필자는 아이폰에서의 최적화를 위해 이 비교를 했는데, 실제 현 세대의 아이폰에서는 C 배열이나 <code>NSArray</code> 배열은 거의 차이가 없다고 합니다. 3GS에서는 아예 완전히 같은 결과가 나오므로 하드웨어 수준의 Objective-C에 최적화가 이루어져을 가능성이 있다는 답글도 있습니다. 답글의 필자가 직접 비교한 결과는 여기에 있습니다.</p>
<p><a href="http://www.formconstant.net/diagrams/?p=40&amp;preview=true">http://www.formconstant.net/diagrams/?p=40&amp;preview=true</a></p>
<p>테스트 내용만 두고 보면 C 기본 배열을 사용하는 것이 좋겠다고 생각했지만, 답글의 내용까지 고려한다면 코코아 프레임워크의 기능을 전혀 제공하 수 없는 C 기본 배열을 굳이 사용할 필요는 없다고 생각됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/321/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SVG와 웹폰트 (웹 상의 폰트 임베딩)</title>
		<link>http://blog.eonil.com/post/302</link>
		<comments>http://blog.eonil.com/post/302#comments</comments>
		<pubDate>Sat, 02 Jan 2010 22:43:40 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/HTML5]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=302</guid>
		<description><![CDATA[플래시의 주요 용도 중 하나는 타이포그래픽입니다. 웹에서 효과적으로 글꼴을 표시할 수 있는 방법이 없기 때문입니다. 국내 업계에서는 플래시만한 대안이 없다고 생각합니다. 하지만 사실은 대안이 있습니다. 그것도 2개나 있죠. 어도비의 SVG 폰트 마이크로소프트의 Embedded OpenType(EOT, 일명 웹폰트) EOT는 싸이월드의 글꼴 등으로 많이 알려져 있습니다. 하지만 별다른 센세이션이나 영향력은 없죠. 왜인지는 모르겠습니다. 그냥 MS기술이라서 그럴까요? 그리고 IE에서만 [...]]]></description>
			<content:encoded><![CDATA[<p>플래시의 주요 용도 중 하나는 타이포그래픽입니다. 웹에서 효과적으로 글꼴을 표시할 수 있는 방법이 없기 때문입니다.  국내 업계에서는 플래시만한 대안이 없다고 생각합니다. 하지만 사실은 대안이 있습니다. 그것도 2개나 있죠.</p>
<ul>
<li>어도비의 SVG 폰트</li>
<li>마이크로소프트의 Embedded OpenType(EOT, 일명 웹폰트)</li>
</ul>
<p>EOT는 싸이월드의 글꼴 등으로 많이 알려져 있습니다. 하지만 별다른 센세이션이나 영향력은 없죠. 왜인지는 모르겠습니다. 그냥 MS기술이라서 그럴까요? 그리고 IE에서만 지원하기에 비전도 없습니다. MS의 비공개 사유 포맷이라 구현하려면 MS의 허가를 받아야 합니다.</p>
<p>여기서 주목해야 하는 것은 SVG 폰트입니다. 왜냐면 어도비가 좋아하는 SVG 표준의 일부이기 때문입니다. 이것은 XML이고, 공개 표준 기술입니다. 사파리, 크롬, 오페라, 파이어폭스가 지원합니다. 한마디로 IE를 제외한 모든 브라우저가 지원한다는 것이죠. 게다가 무엇보다 중요한 것은 어도비의 것이라는 것입니다. 그러니까 앞으로도 어도비가 EOT를 지원할 일은 절대 없을 거란 뜻입니다. SVG폰트라는 공개 표준 대안이 존재하는 이상 구글과 애플도 절대 지원할 일은 없습니다.</p>
<h2>힌팅</h2>
<p>SVG는 힌팅 지원이 없습니다. 힌팅이란 저해상도 디스플레이를 위해 글꼴 모양을 보정하는 기술입니다. 저해상도의 디스플레이에서 글꼴을 렌더링하면 안티알리아싱 기능으로 인해 글꼴이 선명하지 않게 렌더링 될 수 있습니다. 안티알리아싱을 사용하면 시각적으로는 원형에 더 가까운 이미지로 표현되지만, 저해상도 디스플레이에서는 시각적 정확성보다 가독성이 더 중요한 경우가 많습니다. 예를 들면 스마트폰같은 모바일 기기가 그러하죠.</p>
<p>하지만 이건 문제가 안된다고 봅니다. 만약 힌팅이 중요할 정도의 저해상도 기기라면 최적의 글꼴을 기기에 내장하고 있을 겁니다. 그러므로 단순히 내장 글꼴을 사용하도록 세팅하면 됩니다. 이러한 저해상도 기기의 본문에까지 타이포그래픽을 제공하려는 것은 비이성적인 시도입니다. 이러한 기기는 아예 안티알리아싱이 되지 않는 경우도 많습니다. 타이포그래픽이 필요한 곳은 큰 헤딩 텍스트나, 충분한 해상도를 가진 기기의 본문입니다. 장식적 요소로 타이포그래픽을 활용하는 경우에는 가독성보다 형태를 재현하는 것이 더 중요하므로 힌팅이 없는 것이 문제가 되지 않습니다.</p>
<p>하지만 이런 비이성적인 시도를 해야 할 경우도 있긴 있는데, 해당 기기의 기본 폰트가 비이성적으로 품질이 떨어질 경우입니다. 아니라면 정말로 엄청난 수준의 본문 글꼴을 개발해서 꼭 이걸 보여줘야겠다고 생각할 수도 있죠.</p>
<p>저해상도 기기의 본문 전용이라면 힌팅이 없더라도 글꼴을 제작할 때부터 픽셀 그리드에 꼭 맞게 작업하는 등의 방법으로 힌팅을 미리 적용해 본문전용 글꼴을 제작할 수 있습니다. 저해상도 기기의 본문 사이즈는 거의 고정이니 이렇게 해도 문제가 없습니다. 어쩌면 이런 식으로 글꼴의 힌팅 정보를 바탕으로 힌팅이 미리 적용된 새 글꼴을 만들어줄 유틸리티가 나올 수도 있죠. 시장의 요구가 많다면 충분히 가능할 법한 일입니다.</p>
<p>만약 어떤 이유로 인해 지금 당장 힌팅 지원이 필요하다면, 최후의 방법으로 그냥 TrueType/OpenType 글꼴을 바로 링크해도 됩니다.</p>
<h2>용량</h2>
<p>SVG 글꼴이 XML이므로 용량을 걱정할 수도 있는데, SVG는 SVGZ라는 압축된 형태도 지원합니다. 완전히 최적화된 바이너리에는 못미치겠지만, 큰 차이는 나지 않을 겁니다. 또한, 글꼴의 모든 요소를 사용할 필요 없이, 필요한 부분만 추출해서 사용할 수 있기에 최적화 여지는 더 큽니다.</p>
<h2>복제방지</h2>
<p>마이크로소프트가 내세우고 있는 EOT의 한 가지 기능은 복제방지 기술입니다. EOT는 인코딩시 지정된 몇개의 사이트에서만 작동하도록 설계되어 있습니다. DRM 같은 거라고나 할까요?</p>
<p>물론 글꼴의 저작권과 라이센스, 복제 방지는 중요한 이슈입니다. 하지만 이것은 기술적으로 해결할 수 있는 부분이 아닙니다. MS가 제대로 된 복제방지 기술을 선보인 적도 없습니다. 사람들이 윈도우를 복제하지 않는 것은 양심이나 단속 때문이지 윈도우의 복제 방지 기술이 때문이 아닙니다. WGA는 정품 사용자들의 짜증만 유발했을 뿐 복제 방지 자체에는 전혀 도움이 안됐죠. 크랙된 윈도우는 그런 WGA가 없어 더 쾌적하다는 말도 있었습니다! EOT가 널리 쓰이게 된다면 바로 크래킹 툴이 나타날 것입니다. 크랙되지 않는다 하더라도, EOT를 만드는 데 쓰이는 소스인 트루타입 글꼴만 있으면 EOT를 얼마든지 만들 수 있기 때문에 굳이 EOT를 건드려야 할 필요도 없습니다. EOT는 웹 전용이므로 디자인 타임에는 사용할 수 없고, 결국 트루타입이 필요합니다. MS가 EOT에 걸어둔 복제방지 기술은 제작만 어렵게 할 뿐이며, 실제로는 별 도움이 안됩니다.</p>
<h2>현재</h2>
<p>다음은 SVG폰트의 샘플입니다.</p>
<p><a href="http://devfiles.myopera.com/articles/751/SVGfonts_in_HTML.html">ttp://devfiles.myopera.com/articles/751/SVGfonts_in_HTML.html</a></p>
<p><a href="http://devfiles.myopera.com/articles/751/SVGfonts_in_HTML.html"></a>혹시 IE밖에 없는 분들을 위해 스크린샷도 첨부합니다. 녹색 박스 안에 있는 텍스트들은 모두 SVG 글꼴로 렌더링된 것입니다.</p>
<p><a href="http://blog.eonil.com/wp-content/uploads/2010/01/Screen-shot-2010-01-03-at-오전-7.41.14.png"><img class="alignnone size-large wp-image-303" title="Screen shot 2010-01-03 at 오전 7.41.14" src="http://eonil.com/blog/wordpress/wp-content/uploads/2010/01/Screen-shot-2010-01-03-at-오전-7.41.14-1012x1024.png" alt="" width="385" height="389" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/302/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe SVG, and HTML5 Canvas.</title>
		<link>http://blog.eonil.com/post/296</link>
		<comments>http://blog.eonil.com/post/296#comments</comments>
		<pubDate>Sat, 02 Jan 2010 01:10:07 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/HTML5]]></category>

		<guid isPermaLink="false">http://blog.eonil.com/?p=296</guid>
		<description><![CDATA[요 몇일간 플래시 포트폴리오 사이트를 만들기 위해 작업을 하고 있었습니다. FIVe3D  엔진을 사용해 깔끔한 3D벡터 렌더링을 하는 네비게이션을 작성할 생각이었지요. 그런데 한가지 문제가 있었습니다. FIVe3D 엔진은 드로잉 라이브러리일 뿐이라는 거죠. 일러스트레이터로 만들어 둔 벡터 그래픽을 가져올 방법이 없었습니다. 일러스트레이터 플러그인 API에서 PDF API까지 뒤적거리던 중 한 우연히 검색엔진에서 VRML이란 단어를 보았습니다. 그 단어를 본 순간 [...]]]></description>
			<content:encoded><![CDATA[<p>요 몇일간 플래시 포트폴리오 사이트를 만들기 위해 작업을 하고 있었습니다. FIVe3D  엔진을 사용해 깔끔한 3D벡터 렌더링을 하는 네비게이션을 작성할 생각이었지요. 그런데 한가지 문제가 있었습니다. FIVe3D 엔진은 드로잉 라이브러리일 뿐이라는 거죠. 일러스트레이터로 만들어 둔 벡터 그래픽을 가져올 방법이 없었습니다. 일러스트레이터 플러그인 API에서 PDF API까지 뒤적거리던 중 한 우연히 검색엔진에서 VRML이란 단어를 보았습니다. 그 단어를 본 순간 COLLADA와 같이 XML기반의 벡터 그래픽 파일 포맷이 있다는 게 생각났습니다. 바로 구글링을 했죠. 상위에 엔트리 중에서 SVG라는 이름을 확인한 순간 이거다! 하는 생각이 들었습니다.</p>
<h2>어도비</h2>
<p>그와 동시에 떠오른 것은 제발 일러스트레이터에서 익스포팅을 지원해야 할텐데&#8230; 하는 생각이었습니다. 지체없이 일러스트레이터를 켜고 확인해 봤더니 SVG를 그야말로 전폭적으로 지원하더군요. 모든 그래픽이 완벽히 익스포트될 뿐 아니라, 메타정보까지 익스포트가 됩니다. 웹 익스포트로 선택적으로 옵티마이즈 할 수도 있었습니다.</p>
<p>지금 생각하면 좀 우스운 일이죠. SVG에 가장 적극적인 회사가 바로 어도비입니다. SVG라기보다는 어도비는 모든 종류의 2D 벡터 그래픽에서 주도권을 쥐고 싶어합니다. 사실상 벡터 그래픽의 원류격인 포스트스크립트를 만들어낸 장본인이니 벡터 그래픽 세계에서는 터줏대감입니다.</p>
<p>더 놀라운 것은 SVG가 내부 스크립팅을 지원한다는 것입이다! SVG는 벡터 그래픽 마크업 언어인데, 마치 HTML처럼 내부 그래픽 요소들을 스트립팅할 수 있습니다. 다음 링크를 참조바랍니다. SVG를 보려면 표준 기반의 브라우저(크롬, 사파리, 파이어폭스, 오페라 등)가 필요합니다.</p>
<p><a href="http://srufaculty.sru.edu/david.dailey/svg/SVGAnimations.htm#JSAnim">http://srufaculty.sru.edu/david.dailey/svg/SVGAnimations.htm#JSAnim</a></p>
<p>이런 것은 어디선가 본 적이 있죠. 말하지 않아도 알것입니다. 사실 이것은 플래시와 똑같습니다. 지금의 플래시는 온갖 기능이 들어간 잡다한 세트이지만, 기본적으로 플래시는 벡터 기반의 애니메이션 소프트웨어입니다. SVG는 XML로 기술된 초창기 플래시라고 보아도 무방합니다.</p>
<p>SVG를 리뷰하고 나서, 어도비라는 회사가 플래시를 쉽게 포기할 수도 있을거란 생각이 들었습니다. 플래시가 아니라도 어도비는 디자인 업계의 주신이며, 벡터 그래픽에서의 입지도 튼튼합니다. 또한 이미 웹 표준으로 지정되어 있는 SVG가 있으므로, 앞으로도 걱정없습니다. 지금은 플래시를 플랫폼으로 어떻게 밀어보려고 비비고 있지만, 오래 갈 수 있을 것 같지도 않고, 여의치 않으면 버려버리면 그만입니다. 제가 지난번 포스팅에서 언급한 Flash Framework for WebGL의 컨셉이 이미 SVG에 구현되어 있습니다. 어도비는 2D벡터가 전문분야이며, 폴리곤 기반의 3D렌더링은 기술도, 흥미도 없습니다. SVG는 1999년에 이미 표준으로 확정되었습니다. 10년도 더 전에 이미 미래를 다 대비해 두었군요. 역시 업계의 신앙이 될 만 합니다.</p>
<p><strong>HTML5</strong></p>
<p>HTML5에서는 Canvas라는 그래픽 개체를 제공합니다. 저도 아직 자세히는 모르겠지만, SVG 같이 선언형이 아닌라, 플래시같이 명령형의 그래픽 엔진인 것 같습니다. 사실 플래시와 별로 다를게 없습니다. 그리고 캔버스를 지원하는 브라우저는 모두 SVG도 지원합니다. 플래시가 잘 먹히는 것이 어도비로서는 좋겠지만 플래시가 사라져도 별 다른 것은 없습니다. 웹상의 2D 벡터 그래픽 형식은 이미 SVG로 정해져 있고, 플래시가 밀리고 캔버스가 활성화되면 SVG를 기본 포맷으로 사용하겠죠. 어도비 툴셋은 모두 SVG를 지원하니 달라질 것은 없습니다. 플래시는 액션스크립트에 너무 강하게 바인딩되어 있어 재사용하기 힘드니, SVG용으로 비슷한걸 하나 더 만들든지 하겠죠. 어도비의 지위는 흔들리지 않습니다.</p>
<h2>플래시</h2>
<p>예전에는 애플에서 아이폰용 플래시를 지원하지 않는 것은 그것이 느리고 비효율적이라 배터리를 과소비하게 할 것이기 때문이라고 주장하는 것을 믿지 않았습니다. 단지 사용자 경험의 품질을 유지하고, 플래시같은 가상머신 기반 플랫폼에게 주도권을 빼앗기고 싶지 않아서라고 생각했죠.</p>
<p><a href="http://www.albireo.net/forum/showpost.php?p=33104&amp;postcount=2">http://www.albireo.net/forum/showpost.php?p=33104&amp;postcount=2</a></p>
<p>하지만 맥을 몇달간 써 보니 그 말이 이해가 갑니다. 위 글에서도 말하지만, OS X용의 플래시는 느리고 불안정하기 짝이 없습니다. 물론 윈도우용도 불안정하지만 최소한 윈도우용은 OS X 용 보다는 몇 배 빠릅니다. 어느 정도나 느리냐면, 2 GHz의 코어2 듀오 CPU를 장착한 맥북에어로 유튜브 HD 영상을 제대로 플레이하지 못하는 수준입니다. 퀵타임으로는 전혀 무리없이 쾌적하게 볼 수 있는 H.264 영상이지만 플래시에서는 어림도 없습니다. 그야말로 &#8216;작동만 하는 수준&#8217;입니다. 현란한 그래픽을 사용한 FPS게임의 최소사양 같다고나 할까요? 물론 퀵타임은 GPU 가속을 사용하지만 플래시 플레이어도 GPU 가속을 지원한다고 광고하고 있잖아요? 어도비는 최근에 엔비디아와 제휴도 했습니다. 엔비디아 웹사이트에서 어도비 로고를 보고 깜짝 놀랐던게 꽤 오래전 일 같습니다만, 10.2 플레이어에서도 &#8216;모바일&#8217; 버젼만 가속하겠다는 알 수 없는 발표만 하고 있지요.</p>
<p>플래시 플레이어의 퍼포먼스 문제는 그나마 레오파드에서는 좀 더 나았었다는데, 스노우레오파드로 오면서 심해졌다는군요. 64비트로 바뀌어서 그렇답니다. 이것은 어도비가 맥용 플래시 플레이어 최적화를 안하고 있기 때문입니다. 32비트도 대충 만들어주고, 64비트는 아예 관심이 없죠. 윈도우용도 32비트만 최적화되어 있지 64비트는 구경도 못했습니다.</p>
<p>몇년동안 이런 무성의한 플래시 플레이어 지원을 당한 애플로서는 플래시를 보이콧 할만도 합니다. 애플이 아이폰에 플래시를 넣지 않은 것은 진짜 플래시가 너무 느리고 불안정하기 때문인 것이 맞는 듯 합니다. 윈도우용을 생각하면 안됩니다. 아이폰은 OS X인데, OS X에서 플래시는 정말 악의 축입니다. 아키텍쳐가 다르다는 이유로 64비트 윈도우용도 만들어주지 않는 어도비가 ARM용 플레이어를 최적화시켜 줄 리 없습니다. 사파리에 캔버스 기능을 넣게 한 장본인은 어도비였던 것이죠.</p>
<p>이제 어도비가 아무리 애걸복걸해도 애플은 믿지 않을 겁니다. 또한 외부 플랫폼에 질질 끌려다니지 않아도 되니 애플 디바이스에서의 플래시 지원은 전부 물건너간거죠. 또한 모든 브라우저가 캔버스와 WebGL을 지원할테니 경쟁자가 없었던 초창기와 달리 힘겨운 점유율 경쟁을 해야 합니다. 모바일에서는 생명이 끝났다고 생각한다면 너무 이른 추측인가요? 어도비는 처음부터 플래시를 일회용으로 생각했던 것이 아닌가 하는 생각도 드는군요.</p>
<h2>마치며</h2>
<p>앞을 웹이 어찌될지는 알 수 없지만, 어찌되든 2D 벡터 그래픽은 당분간은 어도비가 신앙을 유지할 것입니다. 하지만 SVG와 캔버스를 미리 알아두는 편이 좋겠더군요. 플래시로 먹고사는 입장이지만, 사실 별로 걱정은 안됩니다. 플래시가 사라져도 인터랙티브 그래픽에 대한 요구가 없어지지는 않으니까요. 어떤 기술을 사용하느냐 하는 차이 뿐이죠.</p>
<p>강력한 개발 커뮤니티의 요구에도 불구하고 하드웨어 렌더링 가속을 제공하지 않는 어도비의 횡포에서도 벗어날 수 있고, 스스로 인터넷 세계의 악의 축이라 생각하던 브라우저 플러그인에 의존하지 않고 표준 기반의 구현을 할 수 있으니 더 당당합니다. SVG도 지원하지 못하는 못난 IE는 이제 글렀으니 크롬 프레임이나 설치하라죠.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/296/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone으로 블로깅하기</title>
		<link>http://blog.eonil.com/post/228</link>
		<comments>http://blog.eonil.com/post/228#comments</comments>
		<pubDate>Wed, 16 Dec 2009 10:55:40 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[아이폰]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/2009/12/16/iphone%ec%9c%bc%eb%a1%9c-%eb%b8%94%eb%a1%9c%ea%b9%85%ed%95%98%ea%b8%b0/</guid>
		<description><![CDATA[아이폰을 샀습니다. 딱히 정해진 목적이 있었던 건 아니지만 애플의 브랜드와 입소문, 그리고 모든 종류의 IT분야에서 특별히 대접받고 있다는 사실 하나로 충분했죠. 그리고 날마다 새로운 발견을 하게 되네요. 오늘 워드프레스 사이트에 왔더니 메인에 걸려있는 &#8220;워드프레스 포 아이폰&#8221;. 이 글은 워드프레스 앱 테스트용입니다! 정말 구매당시에는 고민하게 하지만 사용하면 할수록 만족하게 되는 제품입니다. 이런게 애플 브랜드의 핵심이죠. 국내 [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-231  alignright" title="p_2048_1536_22E447A1-0E45-4530-85F1-59F8A2F3EAC4.jpeg" src="http://blog.eonil.com/wp-content/uploads/2009/12/p_2048_1536_22e447a1-0e45-4530-85f1-59f8a2f3eac4.jpeg" alt="" width="346" height="461" /></p>
<p>아이폰을 샀습니다. 딱히 정해진 목적이 있었던 건 아니지만 애플의 브랜드와 입소문, 그리고 모든 종류의 IT분야에서 특별히 대접받고 있다는 사실 하나로 충분했죠.</p>
<p>그리고 날마다 새로운 발견을 하게 되네요. 오늘 워드프레스 사이트에 왔더니 메인에 걸려있는 &#8220;워드프레스 포 아이폰&#8221;. 이 글은 워드프레스 앱 테스트용입니다!</p>
<p>정말 구매당시에는 고민하게 하지만 사용하면 할수록 만족하게 되는 제품입니다. 이런게 애플 브랜드의 핵심이죠. 국내 대기업들도 매스미디어 마케팅으로 눈속임 장사하겠다는 생각은 그만하고 제대로 된 제품을 통해 진정한 고객만족으로 경쟁하겠다는 마인드를 가졌으면 합니다.</p>
<p>사진도 바로 찍어서 올릴 수 있더라구요! 말은 쉽지만 실제는 처음이네요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/228/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>플래시 그래픽 성능 특성</title>
		<link>http://blog.eonil.com/post/226</link>
		<comments>http://blog.eonil.com/post/226#comments</comments>
		<pubDate>Sat, 12 Dec 2009 07:08:01 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=226</guid>
		<description><![CDATA[플래시의 그래픽의 특성은 한마디로 &#8216;벡터 드로잉&#8217;으로 요약할 수 있습니다. 플래시의 드로잉 엔진은 GPU가속을 지원하지 않습니다. 비트맵으로는 높은 수준의 피델리티를 낼 수 없습니다. 하지만 벡터는 해상도에 상관없이 깔끔하게 드로잉되므로 벡터 드로잉이 피델리티를 높일 수 있는 유일한 방법입니다. GPU가속이 지원되지 않으므로, 비트맵/벡터 양쪽 모두 밀도를 높일 수는 없습니다. 최대한 절제된 디테일로 승부해야 합니다. 그래서 복잡한 벡터 데이터인 [...]]]></description>
			<content:encoded><![CDATA[<p>플래시의 그래픽의 특성은 한마디로 &#8216;벡터 드로잉&#8217;으로 요약할 수 있습니다.</p>
<p>플래시의 드로잉 엔진은 GPU가속을 지원하지 않습니다. 비트맵으로는 높은 수준의 피델리티를 낼 수 없습니다. 하지만 벡터는 해상도에 상관없이 깔끔하게 드로잉되므로 벡터 드로잉이 피델리티를 높일 수 있는 유일한 방법입니다.</p>
<p>GPU가속이 지원되지 않으므로, 비트맵/벡터 양쪽 모두 밀도를 높일 수는 없습니다. 최대한 절제된 디테일로 승부해야 합니다. 그래서  복잡한 벡터 데이터인 텍스트의 경우 대량으로 사용하기 위해서는 비트맵으로 캐시를 해야 하게 되는 아이러니한 상황이 벌어지기도 합니다.</p>
<p>플래시 소프트웨어 렌더러의 핵심은 벡터입니다. 비트맵으로의 캐시는 매우 제한된 상황에서만 가능합니다. 또한 많은 상황에서 벡터 드로잉의 성능이 비트맵 드로잉보다 더 좋습니다. GPU를 사용하던 프로그래머라면 이런 상황이 생소할 수 있습니다. GPU 에서는 텍스쳐로 퀄리티를 내는 쪽이 일반적이기 때문입니다. GPU초창기에는 정점 처리 성능이 낮았고, 이에따라 프로그래밍 기법과 툴은 텍스쳐 기반으로 발전해 왔습니다. 물론 지금은 이야기가 조금 다르죠.</p>
<p>하여간 플래시에서는 벡터 드로잉에 기반해 퀄리티를 유지하는 쪽이 좋습니다. 필레이트가 너무 낮기에 텍스쳐에 기반한 퀄리티 전략은 사용하기 어렵습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/226/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>플래시에서 안정적으로 euc-kr/UTF-8 텍스트 디코딩하기</title>
		<link>http://blog.eonil.com/post/198</link>
		<comments>http://blog.eonil.com/post/198#comments</comments>
		<pubDate>Tue, 13 Oct 2009 20:58:35 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=198</guid>
		<description><![CDATA[국제화 응용 프로그램을 만드는 가장 쉬운 방법 중 하나가 유니코드를 지원하는 것이기에, 많은 프로그램들이 유니코드로 만들어집니다. 플래시 또한 메모리 내 문자열에 유니코드를 사용하므로 기본적으로 모든 텍스트를 유니코드로 취급하는 것이 좋습니다. 하지만 국내 서버 환경은 아직 euc-kr인 경우가 많아 서버/클라이언트간 데이터 교환시 문제를 일으키는 경우가 많습니다. 이러한 문제를 해결하려면 커스텀 디코딩을 수행하면 됩니다. 서버상의 특정 URL에서 euc-kr로 [...]]]></description>
			<content:encoded><![CDATA[<p>국제화 응용 프로그램을 만드는 가장 쉬운 방법 중 하나가 유니코드를 지원하는 것이기에, 많은 프로그램들이 유니코드로 만들어집니다. 플래시 또한 메모리 내 문자열에 유니코드를 사용하므로 기본적으로 모든 텍스트를 유니코드로 취급하는 것이 좋습니다. 하지만 국내 서버 환경은 아직 euc-kr인 경우가 많아 서버/클라이언트간 데이터 교환시 문제를 일으키는 경우가 많습니다. 이러한 문제를 해결하려면 커스텀 디코딩을 수행하면 됩니다.</p>
<p>서버상의 특정 URL에서 euc-kr로 인코딩된 텍스트를 읽으려면 이렇게 하면 됩니다.</p>
<ol>
<li><code>URLLoader</code>를 사용해 데이터를 읽되, text모드가 아니라 binary로 읽어옵니다.</li>
<li>읽어들인 데이터는 <code>ByteArray</code>형식입니다. <code>ByteArray.readUTF8()</code> 또는 <code>ByteArray.readMultiByte()</code> 메서드를 사용해 텍스트를 읽습니다.</li>
</ol>
<p>코드로는 이렇게 됩니다. 강조된 텍스트 부분이 핵심입니다. 일반적인 로드 코드와 비교해 보세요.</p>
<blockquote>
<pre><code>package eonil.sample
{
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;

	public class EUCKRLoader
	{
		public function EUCKRLoader(url:String)
		{
			var req:URLRequest = new URLRequest(url);

			// 데이터 포맷을 바이너리로 지정해 원래의 파일 그대로를 로드합니다.
			<strong>ldr.dataFormat = URLLoaderDataFormat.BINARY;</strong>
			ldr.addEventListener(Event.COMPLETE, onLoadCmpl);
			ldr.load(req);
		}
		private function onLoadCmpl(e:Event):void
		{
			<strong>var bin:ByteArray = ByteArray(ldr.data);
			var txt:String = bin.readMultiByte(bin.length, "euc-kr");</strong>
			// 로드된 바이너리는 euc-kr 문자열이므로 euc-kr방식으로 읽습니다.

			ldr.removeEventListener(Event.COMPLETE, onLoadCmpl);

			trace(txt);
		}

		const ldr:URLLoader = new URLLoader();
	}
}</code></pre>
</blockquote>
<p>euc-kr은 물론, 유니코드 문서라도 이러한 방식으로 로드하기를 권장합니다. 텍스트 모드로 파일을 로드할 경우, 인코딩이 자동 선택되는데 이 과정이 명확하지 않아 결과가 불안정해집니다. <code>System.useCodepage</code>를 사용하면 플래시가 구동되는 환경의 기본 인코딩을 사용하므로, 환경 구성에 따라 결과가 달라집니다. 안정적으로 로드하려면 이 메서드를 써야 합니다. UTF-8로 인코딩된 문서의 경우 다음 코드를 쓰면 됩니다.</p>
<blockquote>
<pre><code>// UTF-8 문서의 경우.
var txt:String = bin.readUTFBytes(bin.length);</code></pre>
</blockquote>
<p>물론 가장 중요한 것은 서버상에 존재하는 텍스트의 인코딩을 정확하게 아는 것입니다. 다른 개발자와 협업시, 미리 인코딩 방식을 결정해 전체적으로 사용하는 것이 좋습니다. 텍스트 데이터만으로 인코딩을 정확하게 알 수 있는 방법은 존재하지 않기 때문입니다. BOM(byte order mark)이나 HTTP헤더 검사, 코드 분표 비교 등 여러 가지 방법이 존재하지만, 모두 유추를 돕기 위한 가이드일뿐, 정확한 결과가 보장되어야 하는 곳에서는 이러한 방법에 의존해서는 안됩니다. 정확한 입력 형식을 알지 못하면 출력도 정확할 수 없고, 결국 알 수 없는 버그와 밤샘, 짜증, 마감 초과로 이어집니다. 저는 단순하고 행복한 삶을 원하기에 인코딩을 알 수 없는 텍스트는 처리하지 않습니다.</p>
<p>서버 세팅이 제대로 되어있지 않거나, 서버 프로그램이 유니코드를 지원하지 못하거나, 클라이언트 사정상, 어쩔 수 없이 euc-kr 인코딩을 사용해야 하는 경우가 아니라면, 파일 저장에는 UTF-8을 권장합니다.</p>
<h1>마치며</h1>
<p>프로그램에서 데이터를 로드하는 것은 가장 기본적인 기능입니다. 그런데 이것이 인터넷이라는 다기종 네트워크와 다국어 지원이라는 큰 벽을 만나면서 세상에서 가장 어렵고 까다로운 기술이 되어 버렸습니다. 플래시에서 XML을 로드했는데 내용이 중간에서 짤리거나, 한글만 ?마크로 변하거나, 소스는 잘 보이는데 파싱이 안되거나 하는 문제가 아직도 계속 일어납니다. 어떤 사람은 이런것에 지쳐서 e4x를 버리고 쿼리스트링만 쓰겠노라고 선언하기도 합니다. 물론 클라이언트에 이런 사람이 있으면 정말 때려주고 싶습니다.</p>
<p>이게 다 유니코드를 몰라서 일어나는 일입니다. 이미 모든 컴퓨터가 인터넷에 연결되어 있기 때문에 다국어 문제는 피할 수 없고, 그래서 유니코드를 모르면 제대로 프로그래밍을 할 수 없습니다! -라고 조엘씨가 말했습니다. 저도 전적으로 동의합니다. 그래도 조엘씨같은 미국사람이면 모르는 것이 이해가 되겠지만, 한국과 같이 다국어 문제에 직접적인 관련이 있는 곳에서 프로그래밍을 하면서 유니코드를 모르는 것은 사실 문제가 큽니다. 왜냐면 일상적으로 만나는 문제인데도 문제를 인지하지 못하거나, 인지했더라도 해결 능력이 없다는 증거이기 때문입니다. 그래서 저는 개인적으로 유니코드 개념의 탑재 여부를 프로그래머 능력 평가 기준의 하나로도 생각합니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/198/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActionScript의 변수 범위(scope)</title>
		<link>http://blog.eonil.com/post/195</link>
		<comments>http://blog.eonil.com/post/195#comments</comments>
		<pubDate>Fri, 09 Oct 2009 20:51:50 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=195</guid>
		<description><![CDATA[C++이나 Java 등의 일반적인 C 계열 언어와는 달리 ActionScript는 블록-레벨 변수 범위를 지원하지 않습니다. C계열 언어에서는 변수는 블록 안에서만 유효하며, 블록을 벗어나면 소멸합니다. 하지만 플래시의 변수 최소 범위는 함수입니다. 함수 내 블록 범위의 스쿠핑을 지원하지 않습니다. 또한, 함수 안에서는 변수 선언 위치가 중요하지 않습니다. 선언하기 전에 값을 할당하더라도 문제없이 작동합니다. ActionScript컴파일러가 함수 내 모든 변수 [...]]]></description>
			<content:encoded><![CDATA[<p>C++이나 Java 등의 일반적인 C 계열 언어와는 달리 ActionScript는 블록-레벨 변수 범위를 지원하지 않습니다. C계열 언어에서는 변수는 블록 안에서만 유효하며, 블록을 벗어나면 소멸합니다. 하지만 플래시의 변수 최소 범위는 함수입니다. 함수 내 블록 범위의 스쿠핑을 지원하지 않습니다.</p>
<p>또한, 함수 안에서는 변수 선언 위치가 중요하지 않습니다. 선언하기 전에 값을 할당하더라도 문제없이 작동합니다. ActionScript컴파일러가 함수 내 모든 변수 선언을 앞으로 끌어당기기 때문입니다. 찬반논란이 있을 것 같지만, 기존보다 더욱 &#8216;엄격한&#8217; 언어로 컨셉을 잡은 이상, 순차 실행이 전제된 함수내 변수 선언을 컴파일러가 마음대로 바꾸는 것은 잘못된 디자인이라 생각됩니다.</p>
<p>이러한 사항들 때문에 일반적인 C 계열 언어 스타일로 코드를 작성하면 버그를 만나기 쉽습니다. 블록 레벨 스쿠프가 없다는 것은 이해할만 하지만, C 계열 언어를 표방하면서 컴파일러가 함수 내 코드 실행 순서를 마음대로 바꾸는 짓은 용납할 수 없습니다. 어도비는 순차 변수 선언과 스쿠프를 활성화하는 컴파일러 옵션을 제공해야 할 것입니다.</p>
<p>참조:</p>
<p><a href="http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7f8c">http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7f8c</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/195/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>아이폰의 크로스플랫폼 정책</title>
		<link>http://blog.eonil.com/post/192</link>
		<comments>http://blog.eonil.com/post/192#comments</comments>
		<pubDate>Thu, 08 Oct 2009 16:14:01 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Think]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=192</guid>
		<description><![CDATA[아이폰 SDK가 공개되었을 때 어도비와 썬에서는 각자 이런 발표를 했습니다. SDK를 살펴보니 애플의 서포트 없이도 우리가 직접 플레이어를 만들 수 있을것 같다. 서드파티 어플리케이션으로 반드시 자바를 제공하겠다. 애플에서는 이들의 행보에 별다른 코멘트를 하지 않았습니다. 물론 플래시 플레이어와 자바 런타임은 모두 앱스토어 등재를 거부당했습니다. 어찌보면 웃기는 일이죠. 실제로 이들의 제작이 어디까지 진행됐는진 알 수 없으나, 애플의 [...]]]></description>
			<content:encoded><![CDATA[<p>아이폰 SDK가 공개되었을 때 어도비와 썬에서는 각자 이런 발표를 했습니다.</p>
<blockquote><p>SDK를 살펴보니 애플의 서포트 없이도 우리가 직접 플레이어를 만들 수 있을것 같다.</p>
<p>서드파티 어플리케이션으로 반드시 자바를 제공하겠다.</p></blockquote>
<p>애플에서는 이들의 행보에 별다른 코멘트를 하지 않았습니다. 물론 플래시 플레이어와 자바 런타임은 모두 앱스토어 등재를 거부당했습니다.</p>
<p>어찌보면 웃기는 일이죠. 실제로 이들의 제작이 어디까지 진행됐는진 알 수 없으나, 애플의 확인도 받지 않고 일단 &#8216;제작하겠다!&#8217; 라는 코멘트부터 했을 정도로 어도비와 썬은 정말로 아이폰에 자사 플랫폼을 넣고 싶어합니다.</p>
<p>하지만 아이폰은 자바를 포함해 어떤한 종류의 범용 가상 플랫폼도 지원하지 않습니다. 왜냐면 아이폰은 크로스플랫폼이 필요없기 때문입니다.</p>
<p>가상 머신 기반의 크로스플랫폼이 빛을 발하는 때는 이미 구축되어 있는 수많은 이기종 플랫폼들에 동종의 어플리케이션을 제작/배포해야 하는 때입니다. 그런데 아이폰은 단일 플랫폼입니다. 또한 타 플랫폼에 어플리케이션을 동시 제공할 이유도 없습니다. 아이폰이 지배적인 점유율을 가지고 있기 때문입니다. 게다가 그러한 가상 플랫폼을 지원하게 된다고 해서 갑자기 고품질 어플리케이션이 생겨나지도 않습니다. 애플 입장에서는 아이폰 UX에 대한 고찰없이 타 플렛폼에서 그냥 넘어온 어플리케이션은 자사 제품의 전체 어플리케이션 풀 수준을 떨어뜨리는 해충에 불과하기 때문입니다. 아이폰 어플리케이션은 아이폰에 최적화되어야 하기에 어차피 많은 부분이 수정되어야 합니다. 따져보면 크로스플랫폼이 별 이득이 없죠.</p>
<p>기존의 어플리케이션을 수정없이 쓸 수 있다는 점도 크로스플랫폼의 장점이긴 합니다만, 애플 수준의 UX 퀄리티를 요구하게 되면 크로스플랫폼은 환상일 뿐입니다. 모든 종류의 플랫폼에 착 달라붙는 마술같은 UI를  구현하는 것은 불가능합니다. 가상 플랫폼의 UX를 위해 작성된 프로그램을 애플이 반길리가 없습니다. 엄격한 통제/관리로 품질을 유지하는 것이 핵심 경쟁력인 애플로서는 당연한 선택입니다.</p>
<p>또한, 어쩌면 애플은 코코아로 시장을 지배하려는 야심을 가지고 있는지도 모릅니다. 90년대에 마이크로소프트 윈도우가 그랬던 것처럼요. 지금 모바일의 세계는 PC의 초창기와 같습니다. 지금은 어플리케이션이 폭발적으로 늘어나고 또 필요한 시기이죠. 지금 어플리케이션을 확보하는 플랫폼이 시장을 지배할 것입니다. 애플은 모바일이라는 세계를 통해 정말 절호의 기회를 잡은 셈입니다. (물론 이것은 애플 제품의 품질이 좋았기 때문입니다.)</p>
<p>비단 모바일로 끝나지 않을 수도 있습니다. 애플은 줄곧 홈 어플라이언스 시장을 노려왔습니다. 가전기기처럼 일상에 침투하는 것이 궁극적인 목적일 것입니다. 일단 모바일 플랫폼을 장악하고 나면, 가전 플랫폼에 진입하기는 매우 쉬워질 것입니다.  아이폰으로 중앙 통제되는 가전제품류 (어쩌면 집 그 자체까지)를 상상하면 답이 금방 나옵니다. 아이폰이 아니라 맥이 그 자리를 대신할 수도 있죠. 중요한건 개인 컴퓨팅 디바이스라는 컨셉이 이미 실현되었다는 거죠. 이 디바이스는 지금은 전화기의 형태이지만, 언젠가는 뇌 속에 칩으로 들어갈지도 모르죠. 애플의 미래에서 그 칩의 운영체제는 아마도 Mac OS X겠죠.</p>
<p>애플이 그런 생각을 하고 있다면 플래시나 자바는 말 그대로 적입니다. 이들을 지원하는 것은 적을 내부로 침투시키는 꼴이죠. 플랫폼 주도권을 잡을 수 있는 기회가 왔는데 이 기회를 썬이나 어도비같은 회사에 나눠줄 이유가 있나요? 애플이 후발 주자였다면 이야기가 달라졌겠지만, 운좋게도 빈 고지를 점령했습니다. 수성만 잘 하면 이긴 게임입니다. 그런데 애플은 플랫폼 운영을 너무 잘 합니다. 비전도 있고 퀄리티도 높습니다. 스마트폰 고객 만족도에서 애플의 점수는 타의 추종을 불허합니다.</p>
<p>혹시 제가 모르는 어떤 이유 덕분에 애플이 갑자기 성문을 열 수도 있습니다. 하지만 일단 드러난 이유만을 두고 봤을 때 플래시를 비롯한 어떠한 종류의 가상 플랫폼도 아이폰에는 침투할 수 없습니다. AJAX(=HTML+Javascript)가 유일하게 허용된 가상 플랫폼입니다. 이미 구축된 방대한 양의 웹 어플리케이션들은 아이폰으로서도 끌어안을 가치가 있으며, AJAX자체는 딱히 주인이 없으니까요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/192/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flash Player 10.1 발표.</title>
		<link>http://blog.eonil.com/post/189</link>
		<comments>http://blog.eonil.com/post/189#comments</comments>
		<pubDate>Thu, 08 Oct 2009 15:35:42 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=189</guid>
		<description><![CDATA[플래시 플레이어 10.1이 발표되었습니다. 아래는 어도비의 보도자료입니다. http://labs.adobe.com/technologies/flashplayer10/ 중점적으로 광고하고 있는 기능이 몇개 있더군요. 멀티터치/제스쳐 인식 하드웨어 가속(모바일만?) iPhone지원 하나하나 뜯어보죠. 멀티터치/제스쳐 지원 멀티터치/제스쳐 인식은 칭찬받을만 합니다. 꼭 필요하다고는 하기 힘들지만, 미래를 대비하고, 트렌드를 따라간다는 점에서 중요합니다. 이번에 강조하는 모바일 지원에도 중요하지요. 하지만 어차피 터치 인식같은 입력부를 다듬는 김에 프레셔 인식도 같이 넣어줬으면 했는데 결국 [...]]]></description>
			<content:encoded><![CDATA[<p>플래시 플레이어 10.1이 발표되었습니다. 아래는 어도비의 보도자료입니다.<br />
<a href="http://labs.adobe.com/technologies/flashplayer10/">http://labs.adobe.com/technologies/flashplayer10/</a></p>
<p>중점적으로 광고하고 있는 기능이 몇개 있더군요.</p>
<ul>
<li>멀티터치/제스쳐 인식</li>
<li>하드웨어 가속(모바일만?)</li>
<li>iPhone지원</li>
</ul>
<p>하나하나 뜯어보죠.</p>
<h2>멀티터치/제스쳐 지원</h2>
<p>멀티터치/제스쳐 인식은 칭찬받을만 합니다. 꼭 필요하다고는 하기 힘들지만, 미래를 대비하고, 트렌드를 따라간다는 점에서 중요합니다. 이번에 강조하는 모바일 지원에도 중요하지요. 하지만 어차피 터치 인식같은 입력부를 다듬는 김에 프레셔 인식도 같이 넣어줬으면 했는데 결국 빠졌네요. 프레셔 인식이 그리 어려운 기능도 아닌데 왜이리 인색한지 모르겠습니다.</p>
<h2>하드웨어 가속</h2>
<p>이거를 GPU가속으로 광고하고 있던데요, 솔직히 거의 블러핑 같습니다. 일단 &#8217;3D 렌더링&#8217;이라든가 &#8216;폴리곤 드로잉&#8217; 같은 문구는 전혀 없습니다. 대략 살펴봤지만, &#8216;벡터 렌더링&#8217;이나 &#8216;비디오 디코딩&#8217;이란 문구만 있을 뿐이었습니다. 어도비 직원도 바보가 아닌 이상, GPU를 통한 3D 렌더링 가속이 된다면 대대적으로 홍보했을 테죠. 문구가 없는걸로 봐서는 3D 렌더링 가속은 지원되지 않는 듯 합니다.</p>
<p>결론적으로 모바일 플레이어에서 CPU에 의존해 퍼포먼스가 낮았었는데, 이번에 모바일 GPU를 통한 몇가지 가속을 지원하겠다는 발표 같습니다. 엔비디아라면 퓨어비디오 지원이라는 거죠. 모바일 플랫폼에서는 획기적인 소식일지 모르겠으나, 기대했던 내용도 아니고, 아이폰 지원(다음 단락 참조)도 되지 않기에 의미가 있는지 모르겠습니다.</p>
<h2>아이폰 지원</h2>
<p>어도비 플래시 CS5에서 iPhone로의 퍼블리싱을 지원한답니다. 실제로 작동하는 모습을 공개했다고 하니 뭔가 되긴 되나 봅니다. 하지만 중요한건 그게 아니죠.</p>
<p>FAQ에 이런 문구가 있습니다.</p>
<blockquote><p>When will Flash Player be available on the iPhone?</p></blockquote>
<p>어도비가 좀 불쌍해지는 대목입니다. 윈도우, 리눅스, 유닉스, 안드로이드 등 모든 종류의 플랫폼으로 이미 제품을 완성했으나, 아이폰으로는 시제품조차 선보이지 못하고 있습니다. 애플에서 거부당한 것이죠. 애플이 아이폰을 허가할 생각이었으면 이미 제품이 발표되었어야 합니다.</p>
<p>제생각엔 아이폰이 스마트폰 시장에서 지배적 사업자 위치를 고수하고 있는 동안에는 플래시가 발붙일 가능성은 없습니다. 아마 지원한다는 저 기능은 플래시 프로젝터같은 형태의 독립 실행형 프로그램으로 만들어 준다는 이야기일 것입니다. 이런걸 쓰느니 그냥 코코아로 만들고 말죠.</p>
<p>웹브라우저 플레이어와 프로젝터 실행기는 다릅니다. 사실 프로젝터 실행기는 별 의미도 없습니다. 플래시가 생존하려면 웹브라우저 안에 들어가는 수 밖에 없습니다.</p>
<p>아이폰 고객 만족도가 수준이하로 떨어지거나, 애플이 수익을 포기하고 자선단체로 거듭나지 않는 한, 아이폰에서 웹브라우저상의 플래시 플레이어는 한동안 볼 수 없을 겁니다. 한 10년 정도는 말이죠.</p>
<h2>결론</h2>
<p>10.1은 마이너 업데이트입니다. 뭔가 큰 변화는 없었습니다. 멀티터치/제스쳐 인식 지원이 인상적이긴 했지만, 프레셔 인식도 없고, 하드웨어 3D 가속도 없고, 스레딩도 없고, 아이폰 지원도 안될 것입니다. 아이폰이야 애플에 막혀서 어쩔 수 없다고 하지만, 프레셔나 3D가속 지원이 그다지 어려운 것이 아닌데 차일피일 미루는 것을 보면 왠지 어도비가 기능 지원을 아끼고 있는 듯한 인상을 받습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/189/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>아이폰의 경쟁력</title>
		<link>http://blog.eonil.com/post/177</link>
		<comments>http://blog.eonil.com/post/177#comments</comments>
		<pubDate>Tue, 15 Sep 2009 03:20:19 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Think]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=177</guid>
		<description><![CDATA[어떤 사람들은 삼성과 LG가 휴대폰 제조에서 애플보다 훨씬 더 많은 경험이 있기에 더욱 기술이 축적되어 있고, 아이폰이 나와도 문제없이 경쟁할 수 있다고 생각합니다. 하지만 실제로는 그렇지 않을 것입니다. 왜냐면 실제로는 애플이 경험과 기술에서 더 앞서 있기 때문입니다. 아이폰을 휴대폰으로 생각하면 답이 나오지 않습니다. 하지만 아이폰을 스마트폰이라는 새로운 제품으로 분류하면 답이 보입니다. 스마트폰은 단순한 전화기가 아닙니다. 이름에 [...]]]></description>
			<content:encoded><![CDATA[<p>어떤 사람들은 삼성과 LG가 휴대폰 제조에서 애플보다 훨씬 더 많은 경험이 있기에 더욱 기술이 축적되어 있고, 아이폰이 나와도 문제없이 경쟁할 수 있다고 생각합니다. 하지만 실제로는 그렇지 않을 것입니다. 왜냐면 실제로는 애플이 경험과 기술에서 더 앞서 있기 때문입니다.</p>
<p>아이폰을 휴대폰으로 생각하면 답이 나오지 않습니다. 하지만 아이폰을 스마트폰이라는 새로운 제품으로 분류하면 답이 보입니다. 스마트폰은 단순한 전화기가 아닙니다. 이름에 &#8216;폰&#8217;이 들어간다고 해서 이를 전화기로 착각하면 안됩니다. 스마트폰은 &#8216;휴대용 개인 컴퓨팅 디바이스&#8217;입니다. 전화기처럼 생겼을 뿐, 다양한 디바이스를 장착한 초소형 PC인 것입니다. 그리고 애플은 PC업계의 전통있는 회사입니다. 1976년, IBM보다도 먼저 PC 하드웨어와 소프트웨어를 제조하기 시작한 것이 애플입니다. 약 30여년동안 축적된 개인 컴퓨팅 노하우가 있으며, 세계적으로 퀄리티를 인정받고 있습니다.</p>
<p>개인 수준에서의 컴퓨팅이라는 것은 별게 아닙니다. 원하는 어플리케이션을 실행할 수 있으면 됩니다. 아이폰의 경쟁력은 이 어플리케이션의 수준에서 나옵니다. 그리고 이 어플리케이션의 퀄리티는 기반이 되는 OS와 프레임워크에서 나옵니다. 아이폰의 OS는 임베딩 시스템용으로 커스터마이즈된 Mac OS X인데, 맥 OS는 개발이 시작된 지 10여년 정도밖에 안된 것 같지만 사실은 그렇지 않습니다.</p>
<p>맥 OS의 시초는 1980년대 중반부터 개발된 Nextstep이라 불리는 BSD기반의 워크스테이션용 유닉스 운영체제입니다. 스티브 잡스가 애플에서 쫓겨나서 넥스트란 회사를 세우고 그래픽용 워크스테이션을 만들었는데, 여기에 쓰인 OS입니다. 잡스는 넥스트를 만들때, 애플에서 일한 경험을 살려 완전한 오브젝트 기반의 대화형 OS 프레임워크를 구축했는데 이것이 넥스트스텝입니다. 넥스트의 평가는 매우 좋았지만, 비싼 가격과 함께, 워크스테이션 시장 자체가 매우 축소되어 크게 성공하지는 못했습니다.</p>
<p>애플의 경영난이 가중되어 스티브 잡스가 복귀한 후 잡스는 넥스트스텝에 예쁜 그래픽을 입혀 리브랜딩한 OS를 만들었는데 이것이 Mac OS X입니다. 사실 맥 OS X 는 넥스트 스텝의 버전업 판 정도로 보아도 무방합니다. 기반 구조도 동일하고, 프레임워크도 동일합니다. 대부분의 코코아 프레임워크 개체가 NS라는 이름으로 시작하는데 이는 넥스트스텝을 의미합니다.</p>
<p>하드웨어면에서도, 아이폰은 한번에 나온 것이 아닙니다. 애플은 1998년에 뉴튼이라는 모바일 디바이스를 출시한 적이 있습니다. 이 제품의 컨셉은 정확히 &#8216;개인용 휴대용 컴퓨팅기기&#8217; 지금의 아이폰과 동일합니다. 뉴튼의 출시는 1998년이지만, 개발을 시작한 것은 1989년으로, 약 10여년에 걸쳐 개발되었습니다. 하지만 이 제품은 실패했습니다. 시대를 잘못 타고났다는 말도 있고, 제품의 완성도가 높지 못했다는 말도 있습니다. 실패의 이유는 저도 자세히는 모르지만, 중요한것은 애플이 아이폰같은 그 무언가를 만들기 위해 1990년대부터 10년동안 개발을 했다는 것입니다.</p>
<p>디자인 면에서도, 애플의 디자인은 항상 혁신을 이뤄왔고, 전세계 인더스트리얼 디자인을 주도했습니다. 잡스가 애플에 복귀하면서 <span style="text-decoration: line-through;">데려온</span>발견한* 디자이너 조나단 이브는 초기 투명케이스로 센세이션을 일으킨 아이맥을 시작으로 모든 애플 제품 라인을 디자인했으며, 아이폰도 디자인했습니다.</p>
<p>이제 삼성/LG 등의 휴대폰 제조사와 비교를 해보죠. 하드웨어면에서 이들의 제조력은 상당한 수준입니다. 애니콜은 자동차가 밟아도 통화가되었다는 전설적인 이야기가 있을 정도로 내구성이나 완성도가 뛰어납니다. 하지만 이것은 어디까지나 제조기술의 이야기입니다. 삼성과 엘지의 제품은 대부분 마케팅 흥행을 통해 판매되기에, 하드웨어 구조나 설계에 있어서 깊은 고민을 한 흔적이 없습니다. 이는 이들이 가전 회사이기 때문입니다. 가전제품은 기술적으로 완성 단계에 이르러, 더 이상 발전할 여지가 없기에, 기술적으로는 비교 우위를 보여주기 힘듭니다. 그래서 제품 경쟁은 마케팅이 절대적이며, 이러한 회사에서 만드는 제품이기에 마케팅에 유리한 흥행적인 요소에 치중하게 되는 것입니다. 이러한 것은 동일하게 기술적으로 완성 단계에 이른 휴대폰에서는 맞는 말이지만, 스마트폰은 아직 그 단계가 아닙니다. 그래서 기술적으로 심하게 차별화되며, 마케팅으로는 아무것도 기대할 수 없습니다.</p>
<p>소프트웨어적인 쪽을 보면 더욱 심합니다. 이들은 자체적인 OS나 프레임워크가 없습니다. 사실 이러한 것은 개발이 매우 힘들고, 직접적인 이윤이 생기지 않기에 전통적인 가전 제조사인 이들의 입장에서는 아웃소싱이 적절하다고 생각할 수 있습니다. 하지만 컴퓨팅 플랫폼 제조사의 입장에서는, OS와 프레임워크는 핵심 기술이기에 아웃소싱해서는 안됩니다. 삼성과 엘지의 어플리케이션 질이 낮은 것은 최하단의 OS부터 아웃소싱하기 때문입니다. 전용의 코딩/개발/테스트/디버깅/UI 툴셋을 제공하는 아이폰에 비해 좋은 어플리케이션이 나오는 것이 이상한 것입니다.</p>
<p>이것을 깨달았는지 최근 삼성에서는 리눅스 기반의 OS를 개발하겠다고 발표한 적이 있습니다. 이러한 변화는 상당히 고무할만한 것이긴 하지만, 사실 큰 의미는 없습니다. 기술 격차가 너무 크기 때문입니다. 애플은 개인용 컴퓨팅 플랫폼의 역사 그 자체입니다. 한 때 뒤쳐지기도 했지만, 지금은 다시 전성기를 맞고 있으며, 호환성을 버리고도 재기했습니다. 이들은 모든 종류의 부품을 직접 설계하고, OS를 디자인했으며, 혁신을 주도했습니다. 무엇보다 중요한것은 프레임워크입니다. 플랫폼 호스트로서, 수준높은 어플리케이션을 제작하려면 프레임워크가 가장 중요하다는 사실을 알고 있습니다. 그리고 이들의 프레임워크에 대한 노하우는 30여년에 결쳐 축적된 것으로 나중에는 기업 역량을 집중하기 위해, OS의 하부 기반 구조를 BSD로 대체(즉 아웃소싱)해 버리고 핵심 가치인 프레임워크와 어플리케이션에만 집중합니다.</p>
<p>삼성과 엘지는 분명 이름난 쟁쟁한 기업입니다. 하지만 그들의 이름은 그들이 지금까지 팔아치운 제품의 양과 그에 기반한 엄청난 마케팅 비용에서 비롯된 것이지 제품의 품질 자체는 그다지 명성을 얻은 것이 없습니다. 특히 제품의 최하단에서부터 미래를 내다보는 깊은 고찰이 없기에 가전제품 제조사에서 더 이상 나아갈 수 없습니다. 창업된지 몇십년이 지났지만 그대로인 것은 이들의 기업구조와 문화가 그러한 것을 받쳐주지 못한다는 증거입니다.</p>
<p>컴퓨터가 나왔을 때 범용 계산기기의 컨셉을 가지고 있었습니다. 하나의 기계가 모든 계산을 수행할 수 있는 것이죠. 모든 계산이라는 말은 모든 작업이 되었습니다. 이러한 생각을 한 사람들이 개인용 데스크탑 컴퓨터를 만들었습니다. 이제 그 기계는 유비쿼터스에 맞닿아 있습니다. 하나의 디바이스에서, 모든것이 연결된 네트워크로 연결됩니다. 지금까지 많은 회사들이 유비쿼터스를 외쳐왔지만, 그나마 그에 근접한 것은 애플뿐입니다. 왜냐면 애플만이 제대로 된 컨셉과 기술을 갖고 있기 때문입니다. 광고에서는 줄기차게 유비쿼터스를 외쳐오는 삼성/엘지이지만, 이미 모든것이 연결된 네트워크와 언제나 휴대할 수 있는 디바이스 플랫폼을 갖추고도 똑같은 일을 하지 못했기에 이들의 제품은 더욱 허망하기만 합니다.</p>
<p><em>*조나단 이브가 원래부터 애플에 근무하고 있었다는 지적에 따라 수정했습니다.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/177/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mac상의 플렉스 빌더에서 Ant를 Custom Builder로 사용하면 항상 실패합니다.</title>
		<link>http://blog.eonil.com/post/159</link>
		<comments>http://blog.eonil.com/post/159#comments</comments>
		<pubDate>Sat, 05 Sep 2009 11:59:05 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=159</guid>
		<description><![CDATA[*이 문제는 플렉스 빌더에서 Ant를 시도하던중 발견되었습니다: http://wp.me/pBvNF-2s *이 버그를 알리고 해결하기 위해 별도의 페이지를 만들었습니다. Mac상의 플렉스 빌더에서 Ant를 Custom Builder로 사용하면 항상 실패합니다. 기본 플렉스 프로젝트의 빌더는 기능에 한계가 있어 이를 확장하려면 Custom Builder를 써야 하는데, 외부 프로그램과 Ant 빌더가 지원됩니다. 외부 프로그램 실행은 구현이 간단하지만 크로스플랫폼이 되지 않으므로 Ant를 쓰게 되는데, 막상 Ant를  Custom Builder로 [...]]]></description>
			<content:encoded><![CDATA[<p>*이 문제는 플렉스 빌더에서 Ant를 시도하던중 발견되었습니다: <a href="http://wp.me/pBvNF-2s">http://wp.me/pBvNF-2s<br />
</a>*이 버그를 알리고 해결하기 위해 별도의 페이지를 만들었습니다.</p>
<p>Mac상의 플렉스 빌더에서 Ant를 Custom Builder로 사용하면 항상 실패합니다.<br />
기본 플렉스 프로젝트의 빌더는 기능에 한계가 있어 이를 확장하려면 Custom Builder를 써야 하는데, 외부 프로그램과 Ant 빌더가 지원됩니다. 외부 프로그램 실행은 구현이 간단하지만 크로스플랫폼이 되지 않으므로 Ant를 쓰게 되는데, 막상 Ant를  Custom Builder로 사용하면 아무 이유없이 계속 실해합니다. 하지만 Ant 빌드파일(.xml)을 개별 실행(Run As&#8230;)하면 잘 동작하는 것으로 보아, Ant자체의 문제가 아니라 플렉스 빌더상의 문제라고 생각됩니다.</p>
<p>이 문제는 플렉스가 설치된 경로에 공백이 포함되어 있으면 생깁니다. 플렉스 설치본을 공백이 없는 경로(/test/fb4 등)로 옮기면 문제가 발생하지 않으며 Custom Builder로도 제대로 작동합니다. 하지만 플렉스의 기본 설치 경로에 공백이 포함되어 있으므로, 기본세팅으로는 이 문제를 피할 수 없게 됩니다.</p>
<p>원터치 빌드를 위해 Ant를 사용한다면 Custom Builder로 사용하는 것이 필수입니다. 그래서 이 문제를 해결해 달라고 어도비 버그 시스템에 리포트했습니다. 관심있는 분들은 버그가 해결될 수 있도록 투표바랍니다.</p>
<p>어도비에 제출한 버그 리포트:<br />
<a href="http://bugs.adobe.com/jira/browse/FB-22548">http://bugs.adobe.com/jira/browse/FB-22548</a></p>
<p>*윈도우상에서는 이 문제를 확인하지 못했습니다. 문제에 대한 정보나 해법을 가지신 분은 덧글바랍니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/159/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>플렉스 빌더의 이클립스 플러그인 시험.</title>
		<link>http://blog.eonil.com/post/152</link>
		<comments>http://blog.eonil.com/post/152#comments</comments>
		<pubDate>Fri, 04 Sep 2009 23:51:17 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=152</guid>
		<description><![CDATA[플렉스 빌더 스탠드얼론 버전의 이클립스는 너무 오래되어서 SVN도 잘 안되고 여러 문제가 있습니다. 그리고 이클립스의 문제는 아니겠지만, 컴파일이 너무 오래 걸리고 빌드가 꼬여서 원클릭 빌드가 안되기 때문에 쓰기가 매우 힘듭니다. Ant도 제대로 작동하지 않습니다. 컴파일이 느린것은 참을 수 있지만, 빌드가 꼬이고 한번에 클린 빌드를 만들어내지 못하는 것은 문제가 큽니다. 이번에는 플래시 오서링에서 리소스를 만들어 써 [...]]]></description>
			<content:encoded><![CDATA[<p>플렉스 빌더 스탠드얼론 버전의 이클립스는 너무 오래되어서 SVN도 잘 안되고 여러 문제가 있습니다. 그리고 이클립스의 문제는 아니겠지만, 컴파일이 너무 오래 걸리고 빌드가 꼬여서 원클릭 빌드가 안되기 때문에 쓰기가 매우 힘듭니다. Ant도 제대로 작동하지 않습니다.</p>
<p>컴파일이 느린것은 참을 수 있지만, 빌드가 꼬이고 한번에 클린 빌드를 만들어내지 못하는 것은 문제가 큽니다. 이번에는 플래시 오서링에서 리소스를 만들어 써 보았는데, 플렉스가 이를 지원하지 않아 셸 명령으로 퍼블리시된 SWC/SWF를 수동 카피해야 했습니다. 하지만 기본 플렉스 컴파일 빌드 태스크는 오버라이딩이 안되는데, 컴파일 시점이 애매하고, 셸 명령이 수행되는 시점도 애매해서 정확한 빌드 트리를 만들 수가 없었습니다.</p>
<p>그래서 Ant를 시도해 본 결과, 빌드 자체는 만족스러웠지만, 무슨 오류가 있는지 빌드 명령으로 앤트 빌드가 실행이 안되었습니다. 상당히 좌절했었죠.</p>
<p>마지막 방법으로 FB3를 플러그인 버전으로 최신의 이클립스에 설치해 보았는데, 계속 에러가 났습니다. 알아보니 3.4까지만 정식 지원되고, 3.5부터는 공식적으로 지원불가더군요. 어도비 JIRA에 누가 버그를 올렸는데, 픽스 불가로 공식 종료되었습니다. 하지만 어차피 최신 버젼을 스지 못한다면 구버젼인데, 3.4나 3.3이나 크게 다를 것도 없어보이는데다, 3.3이면 플렉스 빌더 스탠드얼론과 같은 버젼입니다. 나을게 없죠.</p>
<p>그러던 차에 플래시 빌더 4의 베터를 써보았는데, 컴파일이 매우 빠르고 이상하게 오작동하는 것도 없어서 베타를 사용해볼까 해서 이리저리 돌려보았습니다. 그런데 막상 해보려 하니 이거 문제가 많더군요. 일단 Cocoa 기반이 아니라 Carbon 이클립스를 써야 합니다. 애플이 카본을 놔버려서 오픈소스들이 다들 코코아로 이전하고 있는데 이러다간 플러그인을 쓸 수 없게 될지도 모릅니다. 이클립스 파워는 플러그인에서 나오기 때문에, 플러그인이 없다면 사실 이클립스라고 부르기도 힘든 거죠. 카본 의존성은 SWT에 한정이라고 하는데, SWT도 코코아가 나온 마당에 코코아를 아직 지원하지 않고 있다니 이상합니다. 그래도 혹시 하는 마음에 강제로 설치해 실행시켜 보았는데, 역시 에러를 내며 뻗어버렸습니다. 사실 프로덕션용으로 사용할가 하는 생각도 있었지만, 실제 에러를 보니 불안감이 증폭되어 못쓰겠더군요. 결국 코코아 이클립스를 못쓴다면 3.5의 메리트도 없다고 생각합니다.</p>
<p>일단은 3.4에 FB3 플러그인으로 시도해 보고 앤트가 제대로 된다면 여기에 정착할 생각입니다. 앤트가 안된다면 FB4에 3.5 카본으로 시험해보고 앤트가 잘되는 쪽으로 선택하겠습니다.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>둘다 해봣는데, FB3는 앤트가 되질 않고, FB4는 너무 불안해서 프로덕션용으로 쓸 수가 없네요. 원터치 빌드에 대한 어프로치가 잘못된걸까요&#8230; 일단 작업 마무리부터 하고 다른 시도를 해봐야 할 것 같습니다.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>환영을 본 걸까요? FB3 플러그인을 이클립스 3.4에 설치한 것은 앤트가 잘됩니다! 이걸로 결정했습니다! Flex SDK 4 beta도 설치해서 시험해봐야겠네요.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>아쉽지만 제가 본 것은 환영이었습니다. FB3/4 SA/Plugin with 3.3/3.4/3.5 cocoa/carbon 등등 모든 버젼에서 Ant가 Custom Builder 로 작동하지 않았습니다.</p>
<p>대신 원인을 찾아냈습니다. FB가 설치된 디렉토리 경로에 공백문자가 있으면 실패하고, 공백문자가 없으면 잘 되더군요. FB가 Ant를 호출하는 과정에 버그가 있는 것 같습니다. 설치본을 공백문자가 없는 경로로 옮기면 되긴 하지만 버그 회피일뿐, 문제를 해결했다고 보기는 어렵네요.</p>
<p>그래서 어도비에 버그 리포팅을 했습니다. 관심있는 분들은 투표를 통해 해결이 되도록 도와주시기 바랍니다.<br />
<a href="http://bugs.adobe.com/jira/browse/FB-22548"> http://bugs.adobe.com/jira/browse/FB-22548</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/152/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use Ant build in Flex Builder 3.</title>
		<link>http://blog.eonil.com/post/143</link>
		<comments>http://blog.eonil.com/post/143#comments</comments>
		<pubDate>Fri, 04 Sep 2009 21:32:06 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=143</guid>
		<description><![CDATA[There is a final alternative for people to evade Flex Builder&#8217;s mysterious behavior. It&#8217;s Ant build. Becuase the Flex Builder is eclipse, you can use ant build. First, you have to install Ant. It&#8217;s included JDT package. There&#8217;re so many documents which describes it. Google for it. Seconds, you have to register flex ant task [...]]]></description>
			<content:encoded><![CDATA[<p>There is a final alternative for people to evade Flex Builder&#8217;s mysterious behavior.<br />
It&#8217;s Ant build. Becuase the Flex Builder is eclipse, you can use ant build.</p>
<p>First, you have to install Ant. It&#8217;s included JDT package. There&#8217;re so many documents which describes it. Google for it.</p>
<p>Seconds, you have to register flex ant task classes to build flash with ant tasks. I expained the steps to do here.<br />
The steps are simple.</p>
<ol>
<li>Open preference.</li>
<li>Add flash tasks jar as external jar into ant.</li>
<li>Add tasks to use from the jar. I added compc and mxmlc.</li>
<li>Done. You can access compc/mxmlc tasks from ant build XML.</li>
</ol>
<p>*You have to set <code>FLEX_HOME</code> property as Flex SDK folder path to make it work.</p>
<p>I&#8217;ve included screenshots to help you ensure you&#8217;re doing each steps correctly.</p>

<a href='http://blog.eonil.com/post/143/picture-1-2' title='picture-1'><img width="524" height="323" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-11.png" class="attachment-large" alt="picture-1" title="picture-1" /></a>
<a href='http://blog.eonil.com/post/143/picture-4-2' title='picture-4'><img width="951" height="717" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-41.png" class="attachment-large" alt="picture-4" title="picture-4" /></a>
<a href='http://blog.eonil.com/post/143/picture-5-2' title='picture-5'><img width="1024" height="590" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-51-1024x590.png" class="attachment-large" alt="picture-5" title="picture-5" /></a>
<a href='http://blog.eonil.com/post/143/picture-6-2' title='picture-6'><img width="966" height="658" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-61.png" class="attachment-large" alt="picture-6" title="picture-6" /></a>
<a href='http://blog.eonil.com/post/143/picture-9-2' title='picture-9'><img width="700" height="653" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-91.png" class="attachment-large" alt="picture-9" title="picture-9" /></a>
<a href='http://blog.eonil.com/post/143/picture-10-2' title='picture-10'><img width="549" height="436" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-101.png" class="attachment-large" alt="picture-10" title="picture-10" /></a>
<a href='http://blog.eonil.com/post/143/picture-11' title='picture-11'><img width="1024" height="762" src="http://blog.eonil.com/wp-content/uploads/2010/12/picture-111-1024x762.png" class="attachment-large" alt="picture-11" title="picture-11" /></a>

<p>Notice the Ant build log printed as success.</p>
<p>I wish this is helpful to you :)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>I got knew Ant task support adding task classes in jar at runtime. So steps described above is not required.<br />
Refer here for more details: <a href="http://flex.gunua.com/?p=79">http://flex.gunua.com/?p=79</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/143/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>애자일 개발 방법론 &gt; 익스트림 프로그래밍 &gt; 유닛 테스트</title>
		<link>http://blog.eonil.com/post/126</link>
		<comments>http://blog.eonil.com/post/126#comments</comments>
		<pubDate>Tue, 25 Aug 2009 08:50:24 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=126</guid>
		<description><![CDATA[&#8230;가장 큰 부작용이 발생할 때는, 계획대로 진행되지 않을 경우이다. 이럴경우에는 다음과 같은 부작용이 발생하게 된다. 납기일 전 철야 철야에도 불구하고 납기일 지연 지연에 따른 비난과 스트레스가 개발자에게 향하여 에너지 소진 결국 납기된 솔루션은 고객의 요구를 충족하지 못함 위키피디아의 &#8216;애자인 개발 방법론&#8217; 중에서 발췌. http://ko.wikipedia.org/wiki/애자일_개발_프로세스 조엘이 그의 블로그에서도 밝혔듯이, 신기하게도, 고객 요구사항은 계속 변합니다. 왜냐면 고객도 [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;가장 큰 부작용이 발생할 때는, 계획대로 진행되지 않을 경우이다. 이럴경우에는 다음과 같은 부작용이 발생하게 된다.</p>
<ul>
<li>납기일 전 철야</li>
<li>철야에도 불구하고 납기일 지연</li>
<li>지연에 따른 비난과 스트레스가 개발자에게 향하여 에너지 소진</li>
<li>결국 납기된 솔루션은 고객의 요구를 충족하지 못함</li>
</ul>
<p>위키피디아의 &#8216;애자인 개발 방법론&#8217; 중에서 발췌.<br />
<a href="http://ko.wikipedia.org/wiki/애자일_개발_프로세스">http://ko.wikipedia.org/wiki/애자일_개발_프로세스</a></p>
<p>조엘이 그의 블로그에서도 밝혔듯이, 신기하게도, 고객 요구사항은 계속 변합니다. 왜냐면 고객도 그의 요구사항을 잘 모르기 때문입니다&#8230;</p>
<p>자작 프로그램에 있어서 애자일 방법론은 무엇보다 중요합니다. 그 중 유닛 테스트를 필두로 하는 익스트림 프로그래밍이 가장 필요합니다.</p>
<h2>유닛 테스트의 필요성</h2>
<p>제대로 개체 지향적으로 프로그램되어 있다면, 프로그램은 개별적으로 나눌 수 있는 작은 부분들의 느슨한 결합으로 구성되어 있습니다. 이 조각들은 하나 또는 여러개의 클래스 그룹으로 구성됩니다. 이 조각들을 한데 모아 문제를 해결하는 시스템을 구성합니다. 문제는 시간이 없다는 것입니다. 처음에 완벽한 설계를 할 수 없습니다. 기능을 추가하면서 리팩토링을 통해 결과에 도달해가야 합니다.</p>
<p>그 과정에 발견되는 하나의 큰 문제는 조각들의 연결입니다. 개체지향의 가장 큰 이상인 캡슐화를 위해서는 개별 조각들은 서로의 동작을 알 수 없어야 합니다. 단지 다른 조각에 메시지를 보내면 제대로 실행해줄 것이라고 믿는 수 밖에 없습니다.</p>
<p>문제는 디버깅입니다. 많은 연결이 얽혀 있기에, 연결 과정중 두세번만 오차가 누적되어도 디버깅하기가 매우 어려워집니다. 소중한 시간이 디버거를 쳐다보느라 날아갑니다. 조각이 이미 얽혀 있는 상태에서는 버그를 찾기도 어렵고 고치기도 어렵습니다. 조각을 따로 떼서 제대로 작동하는지 여부를 검증해야 합니다.</p>
<p>이러한 코드를 본 프로그램상에 넣을 수도 있지만, 이보다는 별도의 프로그램으로 만들어 빌드과정에서 자동으로 수행되도록 하는 것이 더 좋습니다. 본 프로그램은 되도록 가볍게 유지해야 합니다. 비로직 코드는 리팩토링을 어렵게 하기 때문입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/126/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebGL 발표!</title>
		<link>http://blog.eonil.com/post/120</link>
		<comments>http://blog.eonil.com/post/120#comments</comments>
		<pubDate>Sun, 23 Aug 2009 13:35:25 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Talk]]></category>
		<category><![CDATA[Talk/Think]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=120</guid>
		<description><![CDATA[2009년 8월 4일, 웹GL이 표준으로 공식 발표되었습니다. !!!!!!!!!!!!!!!!!!!!!!!!! 올해의 가장 쇼킹한 뉴스 중 하나이군요. 아래 링크를 참조해 주세요. http://drawlogic.com/2009/08/08/webgl-announced-javascript-controlled-opengl-standard-is-now-official-at-khronos-group-who-runs-opengl-openvg-opengl-es/ http://www.khronos.org/news/press/releases/khronos-webgl-initiative-hardware-accelerated-3d-graphics-internet/ 웹GL은 브라우저 플러그인 없이 리치 3D 웹 그래픽을 표현하기 위한  OepnGL ES 2.0의 자바스크립트 바인딩입니다. 즉, 웹GL을 지원하는 브라우저는 플러그인 없이 완벽하게 하드웨어 가속되는 실시간 3D 그래픽을 표현할 수 있습니다. 오픈GL 표준을 관리하는 크로노스 그룹은 웹GL을 오픈GL표준의 하나로 정하고 공식 발표했습니다. 굵직한 [...]]]></description>
			<content:encoded><![CDATA[<p>2009년 8월 4일, 웹GL이 표준으로 공식 발표되었습니다.</p>
<h2>!!!!!!!!!!!!!!!!!!!!!!!!!</h2>
<p>올해의 가장 쇼킹한 뉴스 중 하나이군요. 아래 링크를 참조해 주세요.</p>
<p><a href="http://drawlogic.com/2009/08/08/webgl-announced-javascript-controlled-opengl-standard-is-now-official-at-khronos-group-who-runs-opengl-openvg-opengl-es/">http://drawlogic.com/2009/08/08/webgl-announced-javascript-controlled-opengl-standard-is-now-official-at-khronos-group-who-runs-opengl-openvg-opengl-es/</a></p>
<p><a href="http://www.khronos.org/news/press/releases/khronos-webgl-initiative-hardware-accelerated-3d-graphics-internet/">http://www.khronos.org/news/press/releases/khronos-webgl-initiative-hardware-accelerated-3d-graphics-internet/</a></p>
<p>웹GL은 브라우저 플러그인 없이 리치 3D 웹 그래픽을 표현하기 위한  OepnGL ES 2.0의 자바스크립트 바인딩입니다. 즉, 웹GL을 지원하는 브라우저는 플러그인 없이 완벽하게 하드웨어 가속되는 실시간 3D 그래픽을 표현할 수 있습니다. 오픈GL 표준을 관리하는 크로노스 그룹은 웹GL을 오픈GL표준의 하나로 정하고 공식 발표했습니다.</p>
<p>굵직한 회사들은 상당수 참여를 했군요. 워킹 그룹에 참여한 회사를 살펴보면,</p>
<ul>
<li>AMD</li>
<li>에릭슨</li>
<li>구글</li>
<li>모질라</li>
<li>엔비디아</li>
<li>오페라</li>
</ul>
<p>입니다. AMD와 엔비디아가 참여한 것을 보면 하드웨어쪽은 완벽히 지원이 될 것이고, 구글/모질라/오페라가 참여했으므로, 크롬/파이어폭스/오페라에서는 곧 지원이 될 것입니다. 더불어 크롬과 같은 엔진을 사용하는 애플 사파리도 언급은 없지만 조용히 지원하게 되겠죠.</p>
<h2>WebGL vs Flash</h2>
<p>애석하게도 어도비는 없습니다. 폐쇄적인 회사 성향을 생각하면 당연하긴 합니다. 웹GL을 플래시의 경쟁자로 생각하는 것이 확실합니다.</p>
<p>실시간 그래픽은 시장에서는 계속 요구된 기능이었지만, 어떤 브라우저도 이를 제공하지 못했습니다. 그 결과 이를 메꾸어줄 플러그인이 나타났는데, 그것이 플래시였죠. 그리고 어도비는 플래시를 사들여 이에 기반한 사업으로 상당한 재미를 보고 있었습니다. 그런데 그 부재된 기능을 하드웨어와 브라우저 벤더가 연합해 해결하겠다고 합니다. 그것도 그저그런 수준이 아니라 &#8216;표준 API를 통한 하드웨어 가속 3D그래픽&#8217;이라는 업계 최고의 구현 수준으로요. 만약 웹GL이 이상적으로 구현된다면 그래픽 성능으로는 플래시 엔진이 따라갈 수 없습니다. 하드웨어 가속도 문제이지만, 브라우저의 샌드박스 안에서만 동작해야 하는 플러그인이 브라우저 자체 기능을 이길 수는 없지요.</p>
<p>현재 플래시가 더 나은 점이라고는 텍스트 표현 뿐입니다. 폰트를 직접 임베드할 수 있다는 거죠. 역시 원천기술을 보유한 회사답게 플래시는 그간 절망적인 웹 타이포그래픽의 희망이었습니다. 이러한 타이포그래피에 대한 요구가 플래시를 좀 더 살려주긴 할 것입니다. 게임 분야는 성능에 목을 매기 때문에 폰트가 좀 구리게 나오더라도 웹GL로 바로 이동하겠지만, 비주얼 디자인 분야는 타이포가 매우 중요하죠.  GL에서 벡터 폰트를 표현하려면 폴리곤 메시로 표현하는 방법밖에 없으며, 텍스트 처리와 레이아웃은 그리 간단 하지 않습니다. 하지만 분명 누군가가 해결해 버릴 것입니다. 시간이 좀 걸릴 뿐이죠.</p>
<p>웹GL을 지원하지 않을 예정인 회사는 웹 세계의 이단아인 마이크로소프트뿐입니다. IE가 아직 절대적인 국내 상황이 약간 걱정이지만, 구글에서 플러그인으로 해결해주겠다고 합니다. 같은 플러그인의 입장이므로 결국 점유율 싸움이 됩니다. IE에서 플래시를 설치한 사용자가 구글 플러그인을 거부할 이유는 그다지 없습니다. ActiveX에 대해 상당한 체험 학습을 한 사용자라면 다소 저항이 있겠지만, 이는 사람들에게 좋은 인식을 얻어 신뢰를 쌓으면 해결됩니다. 게다가 설치를 유도할 떡밥은 3D 게임입니다. 게임 제작사 입장에서 웹GL은 상당히 매력적인 기능이죠. 특히 캐쥬얼 게임을 서비스하고 있다면 굉장히 적극적으로 반응할 것입니다. 정말 기대되는 것은 플래시 게임 업계입니다. 이들에게 하드웨어 가속은 정말 필사적인 요구사항입니다. 하지만 그동안 어도비는 이들의 요구를 저버렸었죠.</p>
<p>이렇게 얘기하면 웬지 플래시가 망할것 같지만, 어도비에게는 다른 선택도 있습니다. 액션스크립트와 플래시 플레이어를 버리는 것입니다. 이것은 플래시 플랫폼 자체를 전부 포기하는 것이 아닙니다. 플래시 플레이어는 가상 머신으로 구현된 렌더링 및 코드 실행 엔진으로서, 브라우저에 렌더링 기능이 없기 때문에 만들어진 것입니다. 렌더링 엔진은 웹 GL로, 실행 엔진은 자바 스크립트로 바꿉니다. 이름은 Flash framework for WebGL 정도가 되면 되겠군요. 여기에는 폰트 메셔와 드로잉 API도 포함되겠죠.</p>
<p>플래시 플랫폼은 렌더링 엔진만 있는 것이 아닙니다. 현재로선 웹GL의 구현 수준은 모르겠지만, 원래의 GL은 매우 로우 레벨의 API로 이것으로 뭔가를 하려면 상당한 프레임워크를 제작해야 합니다. 기존의 플래시 개발자가 이것을 배운다는 것은 쉬운 일이 아닙니다. 이미 제작되어 있고, 그 유용함이 검증된데다 많은 사용자층을 가지고 있는 플래시 프레임워크를 GL로 이식한다면 어도비는 또다른 주도권을 가질 수 있습니다. 태생적으로 액션스크립트와 유사한 자바스크립트를 쓰기에 이전하더라도 기존 플래시 개발자가 배워야할 것은 아주 적게 됩니다. 어도비가 하지 않으면 다른 누군가(아마도 스케일폼일까요?)가 할 것이므로 주도권을 가지고 싶다면 지금 하는 것이 좋습니다.</p>
<p>툴셋도 어도비의 무기 중 하나입니다. 현재도 컨텐츠 업계의 어도비에 대한 믿음은 신앙 수준입니다. 생각해 보세요. 현재의 플래시 툴로 디자인하고 퍼블리시하면 웹GL로 구성된 페이지가 컴파일되어 나온다면요? 어도비는 아직 선택의 여지가 많습니다. 지금이라도 크로노스 그룹에 가입하면 GL API에 영향력을 발휘할 수도 있구요. 현재의 멤버들도 쟁쟁하지만 어도비의 이름은 그들에게도 무겁습니다. 하지만 결정은 빨라야 할겁니다. 구글이 이미 그런 프레임워크와 툴셋을 만들고 있을 것 같으니까요.</p>
<p>실제적으로, 플래시 플레이어는 출력부만 아니라, 입력부분도 있고, 유틸리티한 기능이 많아서 GL만으로 대체는 안됩니다. 하지만 미래는 아직 알 수 없죠.</p>
<h2>WebGL vs Silverlight</h2>
<p>제 생각엔 마이크로소프트의 실버라이트 부서는 지금 죽을맛일겁니다. 플래시와 정면으로 경쟁하려 제품을 냈는데, 아직 기능을 제대로 따라잡지도 못하고 있는 상태에서 더 강력한 경쟁자가 나타났습니다. 그것도 플러그인이 아니라 브라우저 벤더들이 직접 브라우저 차원에서 해결하겠다고 합니다.</p>
<blockquote><p>플러그인이 아니라 브라우저 벤더들이 직접 브라우저 차원에서 해결하겠다고 합니다.</p>
<p>플러그인이 아니라 브라우저 벤더들이직접 브라우저 차원에서 해결하겠다고 합니다.</p>
<p>플러그인이 아니라 브라우저 벤더들이직접 브라우저 차원에서 해결하겠다고 합니다.</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>&#8230;</p></blockquote>
<p>이 문장을 쓰고 나서 저도 놀랐습니다.</p>
<p>마이크로소프트 또한 브라우저 벤더입니다!!! 몰락하고 있다고는 하나, 아직 꽤 점유율 높은 브라우저입니다. 또한, 마이크로소프트는 그래픽 하드웨어 벤더들에게 최우선으로 지원받고 있는 DirectX라는 API를 갖고 있습니다. 이 둘을 합치기만 하면, 웹GL의 역할을 하게 됩니다. IE와 DirectX 둘 다 MS가 원천기술을 갖고 있습니다. 쟁쟁한 회사들의 연합이라 합의가 필요한 GL측과 달리 수뇌부 결정 하나로 모든 것이 이루어질 수 있습니다.</p>
<p>그런데 마이크로소프트는 그렇게 하지 않았습니다. 대신 이들은 닷넷을 만들었습니다. 하지만 닷넷은 생각만큼 잘 안됐죠. 그러다 보니 옆집의 플래시는 잘나갑니다. 하지만 아직 닷넷에 대한 미련을 버리지 못한 터라 닷넷상에 WPF를 만들었습니다. 처음에는 소프트웨어 렌더링을 사용했지만 곧 DirectX구현으로 바꾸었습니다. WPF는 생각보다 괜찮았습니다. 하지만 닷넷이 잘 안되었는데 WPF가 잘 될리가 없죠. 그래서 아예 똑같이 해보자 해서 나온것이 실버라이트입니다. 제가 마이크로소프트 직원은 아니기에 실버라이트가 플래시에서 비롯되었다는 말은 보증할 수 없습니다. 믿지 않아도 됩니다.</p>
<p>이러는 사이에 DirectX 부서에서는 MDX를 만들었습니다. MDX는 DirectX의 닷넷 래퍼입니다. 이것은 한동안 DirectX의 정식 배포본에 포함되어 배포되었습니다. 하지만 무슨생각인지, 중도에 MDX 를 접고 c#한정으로 XNA를 다시 만들었습니다. 폼 UI를 필요로 하는 사람은 윈폼으로 가고, 고성능 3D 그래픽을 필요로 하는 사람들은모두 MDX나 XNA로 갔기 때문에 WPF는 버려졌습니다. 뒤늦게 WPF 부서에서 3D 및 이런저런 기능을 넣은 RIA 데모를 선보였지만 이미 5년전에 Mac OS X에서 다 선보인 기능이라 아무도 관심을 갖지 않았습니다. 그리고 RIA가 필요한 사람들은 웹에서도 되는 플래시로 갔습니다.</p>
<p>그런데 그러는 동안, IE는 아무것도 없었습니다. 이 모든 일들이 IE의 버전이 6에서 7이 되기를 기다리는 사이에 일어난 일입니다. 그동안 마이크로소프트가는 닷넷상에 하드웨어 가속 그래픽을 제공하려는 시도를 3번이나 했지만 IE 7은 탭브라우징 외에는 변한 것이 없습니다.</p>
<p>어차피 독자적인 비호환 기능으로 유명한 IE 입니다. 여기에다 하드웨어 가속 3D 그래픽을 넣을 생각은 왜 하지 못했을까요? 법적인 문제일까요? 한동안 독점 소송에 휘말려 고생을 치렀으니 이해할만도 합니다.</p>
<p>하여간 실버라이트는 만들어졌고 다음 버젼에서는 하드웨어 가속을 지원할 예정입니다. 맥에서는 OpenGL을 통해서 할거라고 합니다. GL을 쓰겠다네요! 맥에는 사파리라는 걸출한 브라우저가 있습니다. 비록 ActiveX는 안되지만 실버라이트를 설치한다고 ActiveX가 되게 되는 것도 아닙니다. 사파리가 웹GL을 지원하게 되면 누가 실버라이트를 설치할까요?</p>
<p>윈도우에서도 타브라우저는 모두 웹GL을 지원합니다. 결국 관건은 IE입니다. 사람들에게 실버라이트나 O3D는 비슷합니다. 듣도 보도 못한 잡것이죠. 이들이 제대로된 하드웨어 가속을 갖추는데는 약간의 시간이 필요할 것이며, 비슷한 시기에 구현을 할 것입니다. 누가 먼저 사람들에게 신뢰를 얻느냐 하는 문제입니다. 그런데, 개발 측면에서 호환성을 생각한다면 실버라이트가 GL의 상대가 될 수 없습니다.</p>
<p>만약 마이크로소프트가 결단을 내려 IE자체에 먼저 하드웨어 가속 가능을 넣는다면 또다시 지리한 점유율 싸움을 할 수도 있을 것입니다. 사람들이 O3D를 받아들이게 하는 것이 먼저일까요, 아니면 마이크로소프트가 IE에 하드웨어 가속 기능을 넣고 이를 사람들이 업데이트하게 만드는 것이 먼저일까요? 한가지 알려드리면, 마이크로소프트 제품의 신기능은 메이저 버전이 3개 정도는 올라가야 쓸만해집니다. 그동안 사용자들은 베타 테스트를 하고 있는 셈이죠. 이에 반해 구글은 처음부터 높은 퀄리티의 제품을 선보이는 것으로 유명하죠. 크롬 1.0이 어땠습니까?</p>
<p>마이크로소프트는 옵션이 몇개 없습니다. 어도비처럼 툴셋신앙이 있는 것도 아니고, 프레임워크도 생소합니다. 기존 개발자도 몇 없죠. 한가지 확실한 것은, 이 상황에서 실버라이트에 시간을 투자하는 것은 낭비라는 것입니다.</p>
<h2>정리</h2>
<p>WebGL은 정말 너무 큽니다. 완전한 쇼크입니다. 플래시 게임 엔진 개발진들은 많은 수가 이쪽으로 돌아서리라 생각합니다. 이렇게 되면 크롬 OS에서 게임도 돌아가게 되겠군요. 구현 수준과 자바스크립트의 성능에 따라 그 향방이 결정될 것 같습니다.</p>
<p>플래시와 실버라이트도 가만히 있지만은 않을 것입니다.  하여간 웹 게임의 시대가 멀지 않았습니다. 빨리 GL을 배워둬야 합니다!</p>
<p>2009.08.23, 에오닐</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/120/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>정확한 소수 계산을 하고 싶다면 어떻게 해야 하나요?</title>
		<link>http://blog.eonil.com/post/118</link>
		<comments>http://blog.eonil.com/post/118#comments</comments>
		<pubDate>Sun, 23 Aug 2009 09:47:45 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=118</guid>
		<description><![CDATA[컴퓨터의 정밀도 한계 때문에 한계 이상의 소수 연산은 불가능하므로, int나 Number는 나눗셈에서 오차가 생길 수 밖에 없습니다. 이러한 오차를 방지해야 한다면, 해결책으로 rational number(유리수) 형식을 사용할 수 있습니다. 유리수 형식은 수학적 정의에 따라 나눗셈 오차가 없습니다. 하지만 수의 표현범위가 더 줄어들고 비용이 크게 늘어나는 것은 피할 수 없습니다.]]></description>
			<content:encoded><![CDATA[<p>컴퓨터의 정밀도 한계 때문에 한계 이상의 소수 연산은 불가능하므로, <code>int</code>나 <code>Number</code>는 나눗셈에서 오차가 생길 수 밖에 없습니다. 이러한 오차를 방지해야 한다면, 해결책으로 rational number(유리수) 형식을 사용할 수 있습니다. 유리수 형식은 수학적 정의에 따라 나눗셈 오차가 없습니다. 하지만 수의 표현범위가 더 줄어들고 비용이 크게 늘어나는 것은 피할 수 없습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/118/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>맥에서는 Thrashing이 없네요</title>
		<link>http://blog.eonil.com/post/99</link>
		<comments>http://blog.eonil.com/post/99#comments</comments>
		<pubDate>Wed, 19 Aug 2009 16:54:29 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=99</guid>
		<description><![CDATA[스래싱은 이런저런 정의가 있지만, 기본적으로 메모리가 고갈되어 계속 가상 메모리(디스크)에 의존하고 있는 상태를 가리킵니다. 흔히 갑자기 하드를 무섭게 긁어대면서 OS가 정지할 것처럼 느려지는 현상을 볼 수 있는데, 이것이 스레싱입니다. 스레싱의 원인은 메모리 부족이 직접적인 원인입니다. 하지만 메모리가 충분하고 여유로운 상황에서도 스레싱이 일어날 수 있습니다. 메모리 자체는 여유가 있더라도 메모리의 주소 공간이 고갈되면 가상 메모리 페이징이 발생해 스레싱 [...]]]></description>
			<content:encoded><![CDATA[<p>스래싱은 이런저런 정의가 있지만, 기본적으로 메모리가 고갈되어 계속 가상 메모리(디스크)에 의존하고 있는 상태를 가리킵니다. 흔히 갑자기 하드를 무섭게 긁어대면서 OS가 정지할 것처럼 느려지는 현상을 볼 수 있는데, 이것이 스레싱입니다.</p>
<p>스레싱의 원인은 메모리 부족이 직접적인 원인입니다. 하지만 메모리가 충분하고 여유로운 상황에서도 스레싱이 일어날 수 있습니다. 메모리 자체는 여유가 있더라도 메모리의 주소 공간이 고갈되면 가상 메모리 페이징이 발생해 스레싱 상태가 될 수 있습니다.</p>
<p>일단 메모리 주소 공간의 고갈은 32비트 OS에서는 매우 흔하게 일어납니다. 최대 주소 공간이 4GB 이므로, 대량 작업을 하고 있다면 몇시간 내로 고갈되어 스래싱 상태에 빠지게 됩니다. 특히 윈도우 XP의 경우, 10년 전에 출시된 OS로 대량 메모리 상황을 잘 관리하지 못합니다. 스레싱이 빈번히 일어나 작업 능률이 떨어지는 주 원인이 됩니다. 게다가 XP는 스래싱 상태가 되면 높은 확률로 다운(크래시)됩니다.</p>
<p>비스타의 커널도 크게 다른 것은 없지만, 64비트의 주소 공간이 있으므로 주소 공간 고갈이 XP보다는 늦게 일어납니다. 그리고 XP보다 약간 더 안정적이기 때문에, 스레싱 상황에서 다운되는 확률이 좀 더 낫습니다.</p>
<p>스래싱이 작업 능률에 영향을 미치는지 여부는 겪어본 사람만이 압니다. 몇 분이 넘도록 하드를 긁다가 운이 좋으면 작업물이 살고, 운이 나쁘면 날아갑니다. 작업물을 잃는 것은 재작업을 의미하며, 사람에 따라 다르겠지만, 작업 효율을 떨어뜨리는 주 원인 중 하나입니다.</p>
<p>지금까지 미처 생각지도 못했지만, 맥으로 바꾼 다음에 스레싱을 겪어본 적이 없습니다. 몇일간 계속 작업을 해도 항상 스무스합니다. 윈도우는 켜놓기만 해도 다운된다는 말을 들어본 적이 있습니까? 시간이 지나면 어떤 식으로든 메모리 소모가 누적되며, 커널이 이를 제대로 처리하지 못하기 때문입니다.</p>
<p>스레싱은 웬만한 작업으로는 생기지 않습니다. 단시간에 GB단위의 데이터 IO가 계속되는 작업은 흔하지 않으며, 이런 대량의 데이터를 다루어야 한다면 윈도우 계열 OS로는 한계라고 생각해도 좋습니다. 스레싱이 당신의 작업을 방해하고 있다면 맥으로의 전환을 심각하게 고려해 볼 때입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/99/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSFL에서 링키지를 제대로 세팅하지 못하는 버그</title>
		<link>http://blog.eonil.com/post/96</link>
		<comments>http://blog.eonil.com/post/96#comments</comments>
		<pubDate>Wed, 19 Aug 2009 14:44:58 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=96</guid>
		<description><![CDATA[JSFL로 라이브러리 심볼의 링키지를 설정할 수 있습니다. item.linkageExportForAS = true; item.linkageClassName = "ClassName"; 하지만 심볼 링키지를 설정하면 네임스페이스를 인식하지 못합니다. 그래서 네임스페이스가 다르더라도 이름이 같은 두개의 클래스는 링키지를 세팅할 수 없습니다. 이 버그만 없으면 폴더 단위로 링키지를 세트해 플래시를 리소스 컴파일러 용도로 편하게 쓸 수 있게 됩니다. 일단 버그는 어도비에 리포트했습니다. 어도비 정책상 2표 이상을 얻어야 버그를 리뷰하니, 버그를 [...]]]></description>
			<content:encoded><![CDATA[<p>JSFL로 라이브러리 심볼의 링키지를 설정할 수 있습니다.</p>
<p><code>item.linkageExportForAS = true;<br />
item.linkageClassName = "ClassName";</code></p>
<p>하지만 심볼 링키지를 설정하면 네임스페이스를 인식하지 못합니다. 그래서 네임스페이스가 다르더라도 이름이 같은 두개의 클래스는 링키지를 세팅할 수 없습니다.</p>
<p>이 버그만 없으면 폴더 단위로 링키지를 세트해 플래시를 리소스 컴파일러 용도로 편하게 쓸 수 있게 됩니다. 일단 버그는 어도비에 리포트했습니다. 어도비 정책상 2표 이상을 얻어야 버그를 리뷰하니, 버그를 고칠 수 있도록 투표바랍니다!</p>
<p><a href="http://bugs.adobe.com/jira/browse/FB-22186">http://bugs.adobe.com/jira/browse/FB-22186</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/96/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>맥에서 화면 캡쳐를 어떻게 하나요?</title>
		<link>http://blog.eonil.com/post/90</link>
		<comments>http://blog.eonil.com/post/90#comments</comments>
		<pubDate>Wed, 19 Aug 2009 11:45:28 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=90</guid>
		<description><![CDATA[윈도우에서는 PrtScr키로 화면 캡쳐를 했었습니다. 하지만 맥에는 이 키의 개념이 없죠. 대신 Grabber 어플리케이션을 주는데 사실 사용하기 꽤나 불편합니다. 이 기능이 없을리가&#8230; 하고 생각하다가 우연히 발견했습니다. 화면 캡쳐 단축키: http://www.apple.com/pro/tips/secretcapture.html 창 단위 캡쳐로 모드 변경: http://www.apple.com/pro/tips/screenshots.html ⌘⇧3로 전체화면 캡쳐, ⌘⇧4로 부분 캡쳐가 됩니다. 부분 캡쳐시에는 크로스헤어 커서가 나타나 원하는 부분을 자를 수 있게 해줍니다. 그리고 이 키로 캡쳐한 [...]]]></description>
			<content:encoded><![CDATA[<p>윈도우에서는 <code>PrtScr</code>키로 화면 캡쳐를 했었습니다. 하지만 맥에는 이 키의 개념이 없죠. 대신 Grabber 어플리케이션을 주는데 사실 사용하기 꽤나 불편합니다. 이 기능이 없을리가&#8230; 하고 생각하다가 우연히 발견했습니다.</p>
<p>화면 캡쳐 단축키: <a href="http://www.apple.com/pro/tips/secretcapture.html">http://www.apple.com/pro/tips/secretcapture.html<br />
</a>창 단위 캡쳐로 모드 변경: <a href="http://www.apple.com/pro/tips/screenshots.html">http://www.apple.com/pro/tips/screenshots.html</a></p>
<p>⌘⇧3로 전체화면 캡쳐, ⌘⇧4로 부분 캡쳐가 됩니다. 부분 캡쳐시에는 크로스헤어 커서가 나타나 원하는 부분을 자를 수 있게 해줍니다. 그리고 이 키로 캡쳐한 이미지는 클립보드에 저장됩니다. 또한, ⌘⇧4 사용시, 스페이스바를 누르면 창 단위 캡쳐 모드가 토글되어 쉽게 캡쳐를 할 수 있습니다.</p>
<p>이 기능은 Preview에 통합되어 있습니다. 프리뷰 상에서 캡쳐를 하면 캡쳐한 이미지가 바로 나타나므로 이쪽이 더 편할수도 있겠네요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/90/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML 임베딩하기</title>
		<link>http://blog.eonil.com/post/83</link>
		<comments>http://blog.eonil.com/post/83#comments</comments>
		<pubDate>Tue, 18 Aug 2009 14:46:10 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=83</guid>
		<description><![CDATA[ActionScript의 [Embed] 구문으로 어떤 바이너리든 임베딩할 수 있다. 이를 사용해 바이너리 형태로 XML을 임베딩할 수 있는데 가장 기본적인 텍스트 형식인 XML이 직접 지원되지 않는 것이 의아했다. 문서에는 명시되어 있지 않지만 XML파일의 직접 임베딩도 가능할 듯 했다. 하지만 실제로 해보면 잘 되지 않는데, 트랜스코더가 XML을 다르게 인식하기 때문이다. 구글링 결과 Idlesun의 블로그에서 해법을 찾을 수 있었다. 원문 [...]]]></description>
			<content:encoded><![CDATA[<p>ActionScript의 <code>[Embed]</code> 구문으로 어떤 바이너리든 임베딩할 수 있다. 이를 사용해 바이너리 형태로 XML을 임베딩할 수 있는데 가장 기본적인 텍스트 형식인 XML이 직접 지원되지 않는 것이 의아했다. 문서에는 명시되어 있지 않지만 XML파일의 직접 임베딩도 가능할 듯 했다.</p>
<p>하지만 실제로 해보면 잘 되지 않는데, 트랜스코더가 XML을 다르게 인식하기 때문이다. 구글링 결과 Idlesun의 블로그에서 해법을 찾을 수 있었다.</p>
<p>원문 링크.</p>
<blockquote><p><a href="http://idlesun.wordpress.com/2008/09/30/embed-a-xml-file/">http://idlesun.wordpress.com/2008/09/30/embed-a-xml-file/</a></p></blockquote>
<p>샘플 코드.</p>
<blockquote>
<pre><code><strong>[Embed(source="sample.xml")]</strong>
private static const SAMPLE:Class;
function test():void
{
    // 클래스를 인스턴싱하지 않고 바로 프로퍼티에 엑세스하는 것에 주의하라.
    var sample:XML = SAMPLE.data;
    trace(sample);
}</code></pre>
</blockquote>
<p>내용은 다음 사항을 주의해야 한다는 것이다.</p>
<ul>
<li>임베드될 XML은 프롤로그를 가질 수 없다.</li>
<li>기본적으로 UTF-8인코딩을 사용해야 하지만, ASCII외의 문자를 사용할 경우에는 UTF-16을 사용해야 한다.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/83/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternative 3D</title>
		<link>http://blog.eonil.com/post/71</link>
		<comments>http://blog.eonil.com/post/71#comments</comments>
		<pubDate>Tue, 18 Aug 2009 09:49:59 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=71</guid>
		<description><![CDATA[일단 링크부터. http://alternativaplatform.com/en/ A3D는 플래시 게임 프레임워크를 목표로 하고 있습니다. 현재는 3D 렌더링 및 강체 물리 엔진 정도가 구현되어 있습니다. 여러가지 잡다한 기능이 없는 대신 오로지 속도 하나에 집중하고 있다- 라고 설명되어 있네요. (http://www.diebuster.com/?p=741#comment-219) 속도 외에는 아무런 기능적인 이점이 없다&#8230;라고 하는데요, 사실 현재 플래시 플랫폼의 게임엔진에서 가장 중요한 것은 속도입니다. 사실 PC 3D게임들은 꽤 오랫동안 라이팅된 [...]]]></description>
			<content:encoded><![CDATA[<p>일단 링크부터.<br />
<a href="http://alternativaplatform.com/en/"> http://alternativaplatform.com/en/</a></p>
<p>A3D는 플래시 게임 프레임워크를 목표로 하고 있습니다. 현재는 3D 렌더링 및 강체 물리 엔진 정도가 구현되어 있습니다. 여러가지 잡다한 기능이 없는 대신 오로지 속도 하나에 집중하고 있다- 라고 <a href="http://www.diebuster.com/?p=741#comment-219">설명되어 있네요. (http://www.diebuster.com/?p=741#comment-219)</a></p>
<p>속도 외에는 아무런 기능적인 이점이 없다&#8230;라고 하는데요, 사실 현재 플래시 플랫폼의 게임엔진에서 가장 중요한 것은 속도입니다. 사실 PC 3D게임들은 꽤 오랫동안 라이팅된 칼라 텍스쳐만 사용했습니다. 그 이유는 오로지 하나, 속도뿐이죠. 래스터라이저와 칼라 텍스쳐 이상의 기능은 신세기가 되어 하드웨어 성능이 여유로워지고 셰이더가 일반화된 이후에나 가능해졌습니다. 그렇다면 이 엔진이 가고 있는 길은 매우 바람직한 것이죠. 여기에 강체 물리까지 기본 내장이라고 하니 사실상 게임에서 필요로 하는 것은 다 있는 것이나 다름없습니다.</p>
<p>거기에 현재의 3D DCC툴들이 내장하고 있는 강력한 맵 베이킹 능력이 합쳐진다면 정말 굉장한 물건이 가능할 것 같습니다. 또한 대부분의 플래시 3D 엔진들이 Z소팅이 되지 않아 높은 입체감을 내기 어려웠는데요, 이것이 해결된 것이 가장 좋아보입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/71/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>getDefinitionByName의 ReferenceError: Error #1065 에러</title>
		<link>http://blog.eonil.com/post/62</link>
		<comments>http://blog.eonil.com/post/62#comments</comments>
		<pubDate>Tue, 18 Aug 2009 08:55:26 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Development/Flash]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=62</guid>
		<description><![CDATA[getDefinitionByName 함수는 flash.util 패키지에 있는 함수로, 런타임에 클래스 이름을 통해 클래스 정의를 얻을 수 있게 해 줍니다. 기본적인 사용법은 다음과 같습니다. var cls:Class = Class(getDefinitionByName("SampleClass")); var smpl:SampleClass = new cls(); 이 함수는 잘 작동하지만, 가끔 ReferenceError: Error #1065 에러를 낼 때가 있습니다. 에러 메시지는 변수가 선언되지 않았다는 내용인데, 이경우에는 변수와는 상관이 없으며, 해당 클래스를 찾지 못했기 때문에 [...]]]></description>
			<content:encoded><![CDATA[<p><code>getDefinitionByName</code> 함수는 <code>flash.util</code> 패키지에 있는 함수로, 런타임에 클래스 이름을 통해 클래스 정의를 얻을 수 있게 해 줍니다. 기본적인 사용법은 다음과 같습니다.</p>
<p><code>var cls:Class = Class(<strong>getDefinitionByName</strong>("SampleClass"));<br />
var smpl:SampleClass = new cls();</code></p>
<p>이 함수는 잘 작동하지만, 가끔 <code>ReferenceError: Error #1065</code> 에러를 낼 때가 있습니다. 에러 메시지는 변수가 선언되지 않았다는 내용인데, 이경우에는 변수와는 상관이 없으며, 해당 클래스를 찾지 못했기 때문에 나는 에러입니다.</p>
<p>제 경우에 이 에러의 원인은 라이브러리 링킹이 잘못되었기 때문이었습니다. SWC 외부 라이브러리에 포함된 클래스를 사용했는데, 소스코드상에는 참조가 없으므로 컴파일러가 해당 클래스를 링크에서 제외시켰던 것이죠. 그러니 런타임에 클래스를 찾지 못해 에러가 난 것입니다.</p>
<p>구글링 결과, 간단한 <a href="http://enricofoschi.wordpress.com/2007/01/30/5/">해결팁 (http://enricofoschi.wordpress.com/2007/01/30/5/)</a>이 소개되어 있습니다만, 이 팁은 이제 필요없습니다. 컴파일러 옵션에 라이브러리의 모든 클래스를 강제로 포함하게 하는 옵션이 생겼거든요.</p>
<p><a href="http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_13.html">http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_13.html<br />
</a>mxmlc 컴파일러 옵션에서 <code>include-libraries</code> 항목을 보세요.</p>
<p>컴파일러 옵션을 사용해 해당 라이브러리를 포함시키면 모든 클래스가 포함됩니다. 기준 경로가 현재 프로젝트의 루트가 아니라 <code>bin</code> 디렉토리라는 것만 주의하면 됩니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/62/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SVN설치</title>
		<link>http://blog.eonil.com/post/250</link>
		<comments>http://blog.eonil.com/post/250#comments</comments>
		<pubDate>Mon, 10 Aug 2009 05:09:55 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=13</guid>
		<description><![CDATA[SVN은 오픈소스 소스관리툴입니다. CVS를 빠른 속도로 대체하고 있다고 합니다. 소스관리툴의 필요성은 버전관리/작업공유 때문이며, 세계적으로 CVS/SVN이 압도적인 대세이므로 이를 사용하겠습니다. 설치하고 시작하기 일단 완전 초기 상태에서도 있는진 모르겠지만, 맥 SDK를 설치하고 난 상태의 맥에는 SVN이 기본 설치되어 있습니다. 한가지 문제가 있는데, Xcode가 특정 SVN에 바인딩되어 있어 SVN을 업데이트 할 수 없다는 것입니다. (업데이트하면 Xcode에서 에러가 납니다.) 기본 설치되어 있으며, [...]]]></description>
			<content:encoded><![CDATA[<p>SVN은 오픈소스 소스관리툴입니다. CVS를 빠른 속도로 대체하고 있다고 합니다. 소스관리툴의 필요성은 버전관리/작업공유 때문이며, 세계적으로 CVS/SVN이 압도적인 대세이므로 이를 사용하겠습니다.</p>
<h2>설치하고 시작하기</h2>
<p>일단 완전 초기 상태에서도 있는진 모르겠지만, 맥 SDK를 설치하고 난 상태의 맥에는 SVN이 기본 설치되어 있습니다. 한가지 문제가 있는데, Xcode가 특정 SVN에 바인딩되어 있어 SVN을 업데이트 할 수 없다는 것입니다. (업데이트하면 Xcode에서 에러가 납니다.)</p>
<p>기본 설치되어 있으며, SVN자체가 유닉스를 기반으로 만들어졌기 때문에 자연스럽게 통합됩니다. 모든 관리 작업은 터미널에서 수행합니다.</p>
<p>SVN의 시작은 리포지토리를 준비하는 것입니다. 이는 <code>svnadmin</code>으로 수행합니다.</p>
<blockquote>
<pre><code>svnadmin create <i>(path-to-repository-root)</i></code></pre>
</blockquote>
<p>제 경우에는 Athene이라는 이름의 외장하드에 저장소를 만들었습니다.</p>
<blockquote>
<pre><code>svnadmin create /Volumes/Athene/Repository</code></pre>
</blockquote>
<p>리포지토리는 한 번 만들고 나면 더 이상 만들지 않아도 됩니다.<br />
리포지토리를 만들면 모든 준비가 끝납니다. 이제 Xcode에서 바로 리포지토리를 엑세스할 수 있습니다.</p>
<blockquote>
<pre><code>file:///Volumes/Athene/Repository</code></pre>
</blockquote>
<h2>서버로 구동하기</h2>
<p>SVN은 파일 시스템으로 바로 엑세스할 수 있습니다. 이경우 사용자 인증이 필요없더군요. 이경우에도 사용자 인증이 가능한지 여부는 잘 모르겠으나, 이렇게 사용하는 것 보다는 서버를 통해 사용하는 쪽이 더 낫다고 합니다. 파일 시스템으로 사용하더라도 락/커밋 등이 제대로 될 것 같지만 확실하지 않아서 서버를 구성했습니다. 서버는 단순히 SVN을 디먼으로 구동하면 됩니다.</p>
<blockquote>
<pre><code>svnserve -d -r /Volumes/Athene/Repository</code></pre>
</blockquote>
<p>이러면 이제 SVN프로토콜을 사용해 접속할 수 있습니다.</p>
<blockquote>
<pre><code>svn://localhost/</code></pre>
</blockquote>
<p>기본적으로는 읽기만 가능하고 쓰기가 되지 않을 것입니다. 네트워크로 엑세스할 때는 사용자 인증이 필요하기 때문입니다. 사용자 인증은 해당 리포지토리의 구성 파일을 편집하면 됩니다. 구성 파일은 열어보면 바로 이해가 가는 수준으로 쉽습니다. 의문점은 웹검색.</p>
<p>서버를 켜는건 알겠는데, 서버를 끄려면 어떻게 해야 하나요. 사실 켜기 전에 이걸 먼저 알아야 하기에 검색을 좀 해봤습니다. 유닉스에서 공통으로 사용되는 디먼 종료법이 있더군요.</p>
<blockquote>
<pre><code>killall <i>(daemon-name)</i></code></pre>
</blockquote>
<p>SVN을 끄기 위해서는 이렇게 해주면 됩니다.</p>
<blockquote>
<pre><code>killall svnserve</code></pre>
</blockquote>
<h2>추가</h2>
<p>아파치를 통해 HTTP프로토콜로 엑세스도 가능하고, 버클리DB를 사용해 효율적인 저장도 가능하다고 하는데,  지금은 필요가 없어서 해보지 않았습니다.</p>
<p>*맥 미니 서버에 소스서버를 설치하는 법을 다시 정리한 포스팅을 새로 올렸습니다. (2010.12.04)<br />
<a href="http://blog.eonil.com/post/502/">http://blog.eonil.com/post/502/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/250/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>화면 캡쳐하기</title>
		<link>http://blog.eonil.com/post/248</link>
		<comments>http://blog.eonil.com/post/248#comments</comments>
		<pubDate>Mon, 10 Aug 2009 01:35:22 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Life/Apple]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=7</guid>
		<description><![CDATA[윈도우에서는 PrtScr 키로 화면 캡쳐가 됩니다. 키를 누르면 캡쳐된 이미지가 클립보드에 저장되죠. 물론 안될때도 있구요. 그 이유는 아무도 모릅니다. 맥에서는 화면 캡쳐 어떻게 하나요? http://support.wordpress.com/make-a-screenshot/]]></description>
			<content:encoded><![CDATA[<p>윈도우에서는 <code>PrtScr</code> 키로 화면 캡쳐가 됩니다.<br />
키를 누르면 캡쳐된 이미지가 클립보드에 저장되죠. 물론 안될때도 있구요. 그 이유는 아무도 모릅니다.</p>
<p>맥에서는 화면 캡쳐 어떻게 하나요?<br />
<a href="http://support.wordpress.com/make-a-screenshot/">http://support.wordpress.com/make-a-screenshot/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/248/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>테스트 포스트입니다.</title>
		<link>http://blog.eonil.com/post/247</link>
		<comments>http://blog.eonil.com/post/247#comments</comments>
		<pubDate>Mon, 10 Aug 2009 01:07:22 +0000</pubDate>
		<dc:creator>eonil</dc:creator>
				<category><![CDATA[Fuzzy]]></category>

		<guid isPermaLink="false">http://strigid.wordpress.com/?p=5</guid>
		<description><![CDATA[워드프레스 정말 좋네요.]]></description>
			<content:encoded><![CDATA[<p>워드프레스 정말 좋네요.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eonil.com/post/247/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

