1.Json 프레임워크 최신버젼을 받는다
cocoa-json_step2

2. 다운받은 파일안의 JSON폴더를 자신의 프로젝트에 카피한다


3. 적용할 클레스에 JSON.h를 임포트 한다.

#import "JSON.h"

4.   SBJSON 오브젝트 작성

// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
    
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSDictionary *object = [parser objectWithString:json_string error:nil];

5. 예제

// Create new SBJSON parser object
SBJSON *parser = [[SBJSON alloc] init];

// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://twitter.com/statuses/public_timeline.json"]];

// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];

// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [parser objectWithString:json_string error:nil];

// Each element in statuses is a single status
// represented as a NSDictionary
for (NSDictionary *status in statuses)
{
  // You can retrieve individual values using objectForKey on the status NSDictionary
  // This will print the tweet and username to the console
  NSLog(@"%@ - %@", [status objectForKey:@"text"], [[status objectForKey:@"user"] objectForKey:@"screen_name"]);
}


Posted by 김반장78
,

[펌] 프레시안 뉴스

2010. 12. 29. 00:28
해마다 연말이면, '올 한 해가 이렇게 빨리 지나갔다니'라며 한숨을 쉬곤 합니다. 하지만 차근차근 돌아보면, 지난해 이맘때와 달라진 게 참 많다는 걸 깨닫게 됩니다. 올해도 마찬가지지요. 경제 분야에선 특히 그랬습니다. 하루하루 바쁘게 살아가는 보통 사람들에겐 낯설던 말들이 어느새 익숙해졌습니다. 그만큼 사건도 많았고, 변화도 컸다는 이야기지요. 주요 20개국(G20) 정상회의, 스마트폰, 소셜네트워크서비스(SNS) 등은 지난해만 해도 보통 사람들이 자주 입에 올릴 일이 없었던 말들입니다.

<프레시안>은 2010년 한국 경제를 3개의
키워드정리하는 연말 기획을 마련했습니다. '스마트(Smart)', '소셜(Social)', '스몰(Small)'이 그것입니다.

올 한 해 동안, 스마트폰과 SNS 등 새로운 정보기술(IT) 서비스가 널리 확산됐습니다. 그리고 이는 우리의 생활과 생각에도 큰 변화를 낳았습니다. 동시에 이는 지식 산업의 중요성을 한국 경제를 이끄는 이들에게 깊이 각인시켜준 사건이었습니다. 이건희 삼성 회장이 경영 복귀 명분으로 내세운 것도 스마트폰 충격이었습니다. 토목 사업에만 열을 올릴 뿐 지식정보 산업은 홀대한다는 비판 속에서 꿈쩍하지 않았던 정부 당국 역시 뒤늦게나마 변화의 필요성을 느끼는 듯합니다. 물론 이런 깨달음이 토목 사업의 축소로 이어지지는 않았습니다. 하지만 다양한 기술과 지식을 아우르는 IT융합 서비스의 중요성은 주요 정책 결정자들이 공감하는 분위기입니다. 이런 변화가 내년에는 어떤 정책으로 이어질지 주목됩니다.

한편, 올해는 극단적인 시장 맹신에 대한 반성이 고조된 해이기도 했습니다. 신자유주의를 비판하는 장하준 교수의 책이 베스트셀러가 된 게 한 예입니다. <정의란 무엇인가>가 신드롬을 일으킨 일 역시 넓게 보면 비슷한 맥락입니다. 우리 국민들은 더 이상 "부자 되세요"라는 외침에 열광하지 않습니다. '단숨에 10억 만드는 비결' 따위에 열광하는 분위기도 한풀 꺾였습니다.

이는 '노력하면 누구나 부자가 될 수 있다'는 희망이 꺾인 탓이기도 합니다. 경쟁의 규칙 자체가 공정하지 않다는 믿음이 널리 퍼진 것이지요. 여기에는 이건희 삼성전자 회장이 큰 역할을 했습니다. 공정과 정의를 생명으로 여겨야 할 사법부가 유독 이 회장에 대해서는 관대했습니다. '공정 사회'를 내건 현 정부 역시 이점에선 다를 게 없었습니다. '법(法)이 정의롭지 않다'는 깨달음은 분명 '정의' 신드롬의 한 이유일 것입니다.

이런 분위기는 다른 한편 사회적(Social) 가치에 대한 관심으로 이어졌습니다. '자유로운 개인'끼리의 공정한 경쟁이 환상이라면, 결국 개인과 개인의 연대가 중요하다는 생각입니다. 과거 '작은 정부'를 내세웠던 보수 정치인들이 경쟁적으로 '복지'를 이야기하는 게 한 예입니다. 적어도 이제는 '누구나 사회적 약자가 될 수 있고, 정부는 이들을 위한 안전망을 만들어야 한다'는 주장을 무시하는 정치인은 살아남기 어렵게 됐습니다.

그리고 이는 '작은(Small) 것'의 가치를 다시 환기시켰습니다. 에른스트 슈마허의 <작은 것이 아름답다>를 다시 읽는 이들도 늘었다고 합니다. 하지만 이는 꼭 철학적인 차원에 그치지 않습니다. 올 한 해를 뜨겁게 달궜던 경제 이슈이기도 합니다. 바로 영세 자영업자들의 생존권 문제입니다. '복지'의 불모지대인 한국에선 영세 자영업이 사실상 사회안전망 구실을 합니다. 좋은 대학을 나와 대기업에서 승승장구하던 이들도 노년에는 딱히 할 일을 찾기 힘듭니다. 하지만 비슷한 경제 규모를 지닌 다른 나라들에 비해 압도적으로 높은 자식 교육비는 이들을 그냥 쉴 수 없게 합니다. 또 1997년 외환위기 이후 고용 불안이 심각해진 탓에 한창 일할 나이에 퇴직하는 경우도 크게 늘었습니다. 아무런 준비 없이 세상에 내던져진 이들이 흔히 하는 게 퇴직금으로 '치킨집'이나 '피자집'을 차리는 것입니다. 그런데 '치킨'과 '피자'가 올해 경제계의 화두로 떠올랐습니다. 그동안 영세 자영업자의 분야였던 이들 업종에 대기업이 뛰어들었던 탓입니다. 롯데마트가 출시한 '통큰 치킨'은 숱한 유행어를 낳기도 했습니다.

선진국에 비해 압도적으로 높은 자영업 비중, 고용 불안, 열악한 사회안전망, 높은 교육비 부담과 아울러서 생각해야 할 문제입니다. 아울러 '작은 기업', '작은 가게'가 '큰 기업', '큰 가게'와 함께 살아가는 경제 생태계를 짜는 문제도 생각해야 할 것입니다. 이는 내년도 한국 경제를 이끄는 이들에게 던져진 숙제입니다.

이런 세 개의 키워드, '스마트(Smart)', '소셜(Social)', '스몰(Small)'은 공교롭게도 모두 'S'로 시작합니다. 전두환 정권 시절, 국민을 어리석게 만들려던 '3S(Screen, Sports, Sex) 정책'이 떠오르기도 합니다. 하지만 2010년의 키워드인 '3S'는 다릅니다. 지식과 사회, 작은 것의 가치를 긍정하는 희망의 싹이라고 봤습니다. 독자님들이 부담없이 읽으면서 올 한 해를 돌아보는 기회가 되길 바랍니다. <편집자>

스마트폰 열풍, 그래서 우린 더 '스마트'해졌나?

올해의 단어로 '스마트폰'을 빠뜨리는 이들은 흔치 않다. 휴대폰무선인터넷이 연결된 작은 컴퓨터처럼 쓸 수 있게끔 한 '스마트폰'은 우리 국민의 온라인 활동 영역을 획기적으로 확장했다. 그리고 이는 트위터 등 소셜네트워크서비스(SNS) 확산과 맞물리면서 한국 사회에 새로운 바람을 일으켰다.

올해 초 '아이폰 쇼크'로 시작된 일련의 흐름에 재계 지도자들도 한방 먹었다는 표정이다. 뒤늦게 스마트폰, SNS 등으로 대표되는 IT융합 서비스에 인력과 예산을 투입하느라 분주하다. 다들 '스마트'를 입에 달고 다니는 요즘, 그래서 우리는 지난해보다 더 '스마트'해졌을까?

장담하기 어렵다. 합리적인 업무 계획 없이 그저 노동시간만 늘리는 업무 방식, 창의적 아이디어를 압살하는 폐쇄적이고 권위적인 의사결정 구조, 자본의 극단적인 집중화 등이 여전한 탓이다. 한국이 '아이폰 쇼크'를 받는 쪽은 될 수 있을 지언정 세계에 이런 '쇼크'를 주는 쪽은 되기 힘든 이유다. 한마디로, 올 한 해를 요란하게 했던 '스마트' 열풍에도 우리 사회는 여전히 스마트하지 못했다는 것. 그리고 이는 '스마트' 열풍의 진앙인 IT업계 역시 마찬가지다.

아이폰 촛불과 트위터, 페이스북…'날개' 단 집단지성

스마트폰 가입자 수는 불과 1년 사이에 80여만 명에서 610여만 명으로 늘어났다. KT경제경영연구소는 이 숫자가 내년에는 1620만 명으로 불어나 전체 휴대전화 가입자의 32%에 달할 것으로 예상했다.

이 급진적인 변화는 스마트폰이라는 기기의 변화가 SNS로 대변되는 웹 환경 변화와 맞물렸기에 가능했다. 그릇과 내용물이 동시에 바뀐 셈이다. 바다 건너 미국의 그것으로만 알려졌던 SNS란 단어가 불과 1년 안에 대중화돼, 이제 한국은 트위터 회원 230만 명 시대(12월 22일 기준, @OikoLab 조사)를 맞았다.

페이스북도 느린 속도지만 점차 영역을 넓혀가면서 어른들의 새로운 놀이터성장하고 있다. 방송통신위원회와 한국인터넷진흥원이 발표한 '2010년 인터넷 이용실태 조사'를 보면 5월 현재 인터넷 이용자 수는 3700여만 명에 달했으며, 이 중 65.7%가 SNS를 이용하고 있었다.

인터넷 환경이 유선에서 모바일로, 획기적으로 확장된 올해를 두고 많은 이들은 "똑똑한 IT가 세상을 바꾼다"라고 여기게 됐다. 실제 기성 권력으로는 통제가 어려웠던 일도 일어났다. 집회 현장에 나간 시민들은 아이폰으로 촛불을 켰고, 전통적인 뉴스매체가 SNS 이용자들의 대화모아 기사화하기도 버거워할 지경이었다. '똑똑한' 시민들은 SNS에서 생각을 공유했고, 스마트폰은 이를 항시적으로 중계해 이른바 '집단지성'의 운동(movement) 가능성을 확장시켰다.

스마트폰 열풍은 단순히 정치지형을 바꾼 것에 그치지 않고, 우리 사회 곳곳에 스며들어 새로운 문화를 낳았다. 기업과 언론사는 물론, 정부마저 누리꾼과의 소통을 위해 SNS 관리에 큰 신경을 쏟게 됐다. 스마트폰 환경에 맞는 어플리케이션이 줄줄이 쏟아져 나왔고, 이 환경에 적응한 누군가는 경제적으로도 큰 보상을 받았다. 이 모두 불과 1년 전만 해도 상상하기 어려웠던 일들이다.

'스마트' 열풍의 핵심은 요약하자면 기성에 대한 극복, 극단적인 효율성, 즉각적인 감성에의 호소가 될 것이다. 새로운 아이디어가 각광받고 단순하고 소비자 지향적인 제품이 널리 팔렸으며, 지식 콘텐츠의 중요성이 부각된 게 증거일 것이다. 당초 스티브 잡스가 아이폰에 단 하나 달린 버튼마저 없애려 했던 점, 어플리케이션 개발자와의 수익배분을 중시했던 점 등이 대표적 예다.

IT개발자는 '삽질' 중

▲뒤늦게야 국내 시장이 받아들인 애플의 아이폰은 업계 생태계까지 뒤흔들었다. 스마트폰 열풍은 경제계뿐만 아니라 사회 전체를 크게 움직였다. 그러나, 이동통신요금의 급증은 해결해야 할 숙제다. ⓒ뉴시스
그런데 이런 충격은 한국 사회의 단단한 껍질에 튕겨져 나왔다. '스마트' 열풍을 가장 직접적으로 맞은 IT 업계가 별로 변한 게 없다는 게 그 증거다.

IT산업 종사자들에겐 전혀 새롭지 않은 이야기지만, 한국의 IT산업을 움직이는 논리는 건설업의 그것과 완벽하게 같다. 합리적인 일정 관리, 효율적인 업무 계획 없이 일단 노동력 투입만 늘리고 보는 구조다. '갑을관계'로 대표되는 하도급 구조 역시 견고하다. 홈페이지 제작사에서 근무한 김모 씨(25)는 "24시간 업무 대기 상태"라며 "프로젝트가 연달아 하청구조를 타고 내려오니 개발자들은 항상 초죽음"이라고 말했다. (☞관련 기사 : '일의 노예'… 한국의 IT개발자가 사는 법)

건강에 이상신호가 온다는 말들은 많은 직장인들이 하지만, IT업계만큼 이 말이 농담처럼 지나가는 곳은 드물다. 실제 한 3차 하도급 업체에서 근무하는 노동자 A씨는 "원청업체 단지 안에 외주업체를 위한 단지가 있다. 그곳을 하청업체 개발자들은 감옥에 비유한다. 거기서 시키는대로 일해야 한다"고 하소연했다. (☞관련 기사 : "사람 잡는 야근…폐 잘라낸 SI개발자")

정부 정책은 훌륭히 세워졌지만 지켜지지 않는다. 중소 IT업체 관계자들은 공통적으로 "새 제도 개설이 필요한 게 아니다. 있는 제도가 제대로 지켜지도록 감독을 강화해달라"고 요구한다. 정부의 감독만 강화돼도 업계에서 생각하는 상식이 '몰상식'이라는 점을 사람들이 알게 된다는 말이다. (☞관련 기사 : IT개발자 잔혹사, 정부는 無대책)

이는 노동자의 창의력을 중시하는 기업 문화, 이를 바탕으로 자연스럽게 혁신이 이어지는 기업경쟁력을 IT업계의 기본으로 꼽는 피상적 인식과 거리가 멀다. 해외의 IT기업과도 모양새가 다르다. 애플에 부품납품 계약을 체결한 국내 중소기업의 한 노동자는 자신의 블로그에 애플과 국내 대기업의 차이를 조목조목 설명해, 누리꾼들의 공감을 크게 얻었다.

"'접대' 없이 어떻게 장사하느냐"는 대기업 직원

애당초 특정 산업이 전체 산업의 논리에서 자유로울 수 있다는 믿음 자체가 허구다. IT산업이건, 문화예술 산업이건 마찬가지다. 그리고 한국의 산업 생태계를 관통하는 원리는 과거 박정희 개발 독재 시대에 만들어졌다. 이를 가장 잘 구현한 업종은 건설업이다.

관공서와 대기업, 이른바 '갑'에게 '로비'하는 게 중요하고, 그래서 '술자리'가 잦다. 보통은 '아가씨 있는 술자리'다. 일단 일감을 따내기만 하면, 일은 하청업체와 비정규직이 한다. 꼼꼼한 뒷마무리, 더 나은 제품이나 서비스를 위한 연구개발은 늘 뒷전이다. 시쳇말로 '삽질'의 연속이다. 이런 경제 생태계에서 굳이 '스마트'해질 필요는 없다. 대신 '유들유들함'과 '뻔뻔함', 그리고 '무조건 근면'과 '복종'이 미덕이다. 이래서는 '제2의 아이폰'은 기대하기 어렵다.

지난 11월 주요 20개국(G20) 정상회담 직전, <월스트리트저널>은 "기적은 끝났다. 앞으로의 방향은"이라는 제목의 한국 특집 기사에서 '밤 문화'가 중요한 한국 사회의 비즈니스 관행을 지적한 후, 이를 과거 국가개발주의 전략의 모형으로 지적하고 그 한계가 가까워졌다고 밝혔다. (☞관련 기사 : "G20 열리는 한국, '룸살롱 비즈니스' 나라)

실제로 한 대기업 영업팀 직원은 "자회사 출신이 여행업체를 차려 이른바 '접대' 사업을 전담하고, 회사는 이 회사에 주는 돈으로 접대비를 비용처리한다. 당연히 접대에는 '흔히 생각하는 과정'이 다 포함된다"며 "이렇게 안 하고 어찌 장사 하나. 어차피 공공연한 비밀 아닌가"라고 말했다. 한국 경제의 속살은 바뀐 게 없다는 이야기다.

안상수 '자연산' 논란의 또 다른 진실

이런 점에서 안상수 한나라당 대표가 일으킨 이른바 '자연산' 논란은 시사적이다. 주요 언론은 안 대표의 말 실수에만 초점을 맞췄지만, 진짜 주목할 대목은 따로 있다. 여전히 한국의 권력은 룸살롱으로 대표되는 은밀한 거래환경에서 작동한다는 점이다. 정치권력이건, 경제권력이건 다르지 않다.

경제학자라면 누구나 이런 경제 모델이 나쁘다는 걸 안다. 의사결정의 투명성이 떨어진다는 점, 거래비용이 늘어난다는 점, '룸살롱'으로 대표되는 지하경제는 세수를 악화시켜서 국가 재정을 망친다는 점 등이 그 이유다.

정치, 경제 권력은 언제까지 '룸살롱' 비즈니스에 머무를까. 올해 초 겪은 '아이폰 쇼크'와 올해 말 겪은 '자연산' 논란을 함께 떠올리면 드는 의문이다.
Posted by 김반장78
,
일단. 어떤것을 쓰던간에.. 화일은 잘 읽힌다.. 또한 유니코드의 경우 는 더욱더 편하게 읽힌다.
문제는... 유니코드가 아닌화일을 읽을때 글자깨짐이 일어난다는 점이다.
다음의 경우 Shift_JIS 화일을 읽어들인다. 글자 안깨진다...
다음의 method를 보면 알겠지만.. 인코딩 관련 지정이 하나도 없다..
왜일까? 인코딩을 사용하면 도리어 글자가 깨진다..왜지?

/** ディレクトリからファイルを読取って文字列に返す。
  * @param workName 作業名
  * @return
  */
 public void inputFile(String fileName) {
  BufferedInputStream is = null;       // inputStream初期化
  try {
     StringBuffer returnStr = new StringBuffer();     // ファイル内容を文字列で格納するStringBuffer。

    File inputFile = new File(fileName);       // ファイルを宣言する。
    if (inputFile.isFile() && inputFile.exists() ) {    // ファイルが存在するのを確認
     is = new BufferedInputStream(new FileInputStream(fileName));  // ファイルをstreamで読み取る。
     byte[] byteBuf =new byte[(int) inputFile.length()];  // 一時的にファイルをByteで格納するbyte配列
     for(int j = 0; j < (int) inputFile.length() ; j++) {
      byteBuf[j] = (byte) is.read();       // ファイルをByte読み取る。
/* 바로 이부분이다..왜 바이트로 읽는냐..바보 아니냐 하겠지만..
   다 이유가 있다... 한자 때문이다. Shift_JIS와 unicode는 100%호완되지 않기 때문에.
MS사이트에서 뒤지면 코드 변환표가 나온다..
자바는 내부적으로 유니코드로 처리하기 때문에..
reader를 사용하면.. 깨지는 글자가 생기기 때문이다..
reader에 인코딩 지정해도..결국 깨지는 글자가 발생했다..쩝..왜..그럴리가 없어야 되는데말이지.
단순히 커뮤니티 정도 만들려면..굳이 이렇게 쓸필요없지만..공공기관용을 만들어야 한다면..
어쩔수 없다... 아직까지는..더 좋은 방법을 찾지 못했다는말이지..
*/
     }
     returnStr.append(new String(byteBuf));      // ファイル内容を文字列で格納する。

    } // if (f.isFile() && f.exists()
    is.close();

  } catch (UnsupportedEncodingException e) {    // 支援しないコードの場合
   logger.error("지원하지 않는 인코딩", e);
  } catch (FileNotFoundException e) {      // ファイルが存在しない場合
   logger.error("화일을 찾을수 없다", e);
  } catch (IOException e) {        // 入出力エラーの場合
   logger.error("입출력에러", e);
  } catch (NullPointerException e) {      // 引数がNullの場合
   logger.error("null발생", e);
  }finally{
   try {
    if (is != null) is.close();      // 最後に inputStream を閉じられなかった場合閉じる。
   } catch (IOException e) {       // 入出エラー場合
      }
  } //finally

 } // inputFile(String fileName)

/**ファイル出力処理を行う。 화일 출력이다..뭐..출력은..그다지 상관 없다...잘 되니까..
  * @param str 受け取って編集済みデータ 받아와서 편집끝낸 화일내용
  * @param date 日付 시스템 날짜
  */
 public void outputFile(String str, String fileName ) {

  OutputStreamWriter os = null;       // 出力streamWriterの初期化 초기화..
  try {
   os = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fileName)),"Shift_JIS"); // ファイル出力する。
   os.write(str);          // ファイル内容を記録する。 화일내용을 쓰는 부분..
   os.flush();           // ファイルを放出する。(生成する) 화일을 출력하는부분.
  } catch (IOException e) {        // 入出力エラーの場合
   logger.error("IO에러", e);
  } finally { //연습할때는 finally부분까지는 필요 없다.. 에러처리라는게..연습목적은 아니니까..
   try {
    if (os != null) os.close();      // 最後に outputStream を閉じられなかった場合閉じる。
   } catch (IOException e1) {       // 入出エラー場合
    logger.error("IO에러 ",e1);
   }
  } // finally
  } //outputFile(String str, String date)

이렇게 해서 Shift_JIS에서 화일 입출력은 끝냈따..
그럼 UTF-8화일일 경우에는?
자신이 편한대로 하면 된다..
 /** ファイル読み取る。
  * @param strAddress ファイル住所
  * @return ファイル値文字列
  */
 public String inputFile(String strAddress){
  DataInputStream is = null;       // データinputStream初期化
  StringBuffer returnStr = new StringBuffer();
  try {
   File tempfile = new File (strAddress);    // ファイル宣言
   if(tempfile.exists()){       // ファイルが存在する場合
    byte[] byteBuf = new byte[(int) tempfile.length()];  // 一時的にコード変換ファイルを格納するbyte配列
    is = new DataInputStream(new BufferedInputStream(new FileInputStream(tempfile))); // ファイルinputStream宣言
    while (is.read(byteBuf, 0, byteBuf.length) != -1){   // ファイル読み取る。
     returnStr.append(new String(byteBuf, "UTF-8"));   // ファイル内容を文字列で格納する。
    } //while
   } // if (tempfile.exists()
   is.close();  

  } catch (FileNotFoundException e) {     // ファイルが存在しない場合
   logger.error("화일 안보여", e);
  } catch (IOException e) {       // 入出力エラーの場合
   logger.error("IO에러다", e);  
  }finally{
   try {
    if (is != null) is.close();     // 最後に inputStream を閉じられなかった場合閉じる。
   } catch (IOException e) {     // 入出エラー場合
   logger.error("IO에러다", e);  
   }
  } //finally
  return returnStr.toString();
 } // end od inputFile


Posted by 김반장78
,

u Associative References

n  용도

기존의 클래스오브젝트의 인스턴스변수를 의사적으로 추가

Associative ReferencesMac OS X v10.6이후 에서만 사용 가능

 

n  Adding Storage Outside a Class Definition

클래스 선언을 변경하지않고 오브젝트에 스토리지를 추가 가능

클래스 소스코드에 접근 불가한 경우에 사용 가능

 

n  Creating Associations

런타임 함수 objc_setAssociatedObject를 사용

objc_setAssociatedObject 4개의 인수가 필요 (소스오브젝트, , , 폴리시정수)

(void포인터) : static변수를 사용하는 것이 일반적

폴리시정수 : 관련오브젝트를 대입할것인지, 유지할것인지, 복사할것인지를 지정

static char overviewKey;

NSArray *array = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil];

NSString *overview = [[NSString alloc] initWithFormat:@"%@", @"First three numbers"];

objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);

[overview release];

// (1) overview valid

[array release];

// (2) overview invalid

 

 

n  관련 오브젝트의 취득

NSString *associatedObject = (NSString *)

objc_getAssociatedObject(array,&overviewKey);

 

n  Breaking Associations

objc_setAssociatedObject(array, &overviewKey, nil,

OBJC_ASSOCIATION_ASSIGN);

 

 

 

Posted by 김반장78
,

u 카테고리와 확장

n  의미

기본은 수직상속만 가능, 메소드를 추가해야할 경우 수직상속

카테고리를 사용함으로서 메소드의 수평적 상속이 가능

소스를 가지고 있는 않은 클래스에도 추가할 수 있음

카테고리를 사용해서 클래스의 implementation을 여러 파일로 쪼갤 수 있음

선언과 구현이 분리되어 있고, 클래스에 종속되어 있지 않음

 

n  Adding Methods to Classes

카테고리가 클래스에 추가한 method들은 클래스의 subclass 의해 상속

#import "ClassName.h"
 
@interface ClassName ( CategoryName )
// method declarations

@end

             -특징

               파일명이 ClassName+CategoryName.m으로 됨

#import "ClassName+CategoryName.h"
 
@implementation ClassName ( CategoryName )
// method definitions

@end

               오직 method 추가할 있음

               클래스 scope 모든 instance variables(@private조차도) 카테고리의 scope이므로

모두 접근이 가능

무한정 작성 가능

 

n  How you Use Categories

다른 implementation 의해 정의된 클래스들을 확장할

Cocoa frameworks 정의된 클래스들에 method들을 추가할

             subclass 대안으로 쓰려고

             클래스의 implementation 개의 소스 화일로 분배하려

             informal protocol 선언하기 위해

 

n  Categories of the Root Class

super 대한 message 가능

class object 루트 클래스에 정의된 instance method 수행할 있다

             보통 class object class method 수행하지만 루트 클래스에 정의된 instance method

특별한 경우이다.

카테고리로 추가한 instance method가 루트 클래스에서 수행되므로 예측이 불가능하게 되어 루트

클래스에 카테고리 사용은 바람직하지 못하다.

Posted by 김반장78
,

u 프로퍼티

n         프로퍼티 선언

Property 사용하기 위해서 일반적으로 @property 지시자와 @synthesize 지시자를 함께 사용

@property 지시자는 클래스의 @interface 내부에 선언하며 다음과 같은 형식으로 선언

@interface MyClass : NSObject
{
    float value;
}
@property float value;

@end

 

@property float value

위의 선언은 다음과 같이 두가지 메서드를 선언한것과 같은 기능

- (float)value;

- (void)setValue:(float)newValue;

 

n         @synthesize

구현부안에 getter, setter를 지정안했을경우@synthesize를 통해 컴파일러에게 작성을 지시함

- 주의

  @synthesize를 사용안할 경우 직접 구현부에 getter, setter를 작성해야 컴파일 가능하나

  문제가 발생할 여지가 있으므로@synthesize사용을 권장

 

n         @property 지시자의 attributes

- getter=gettername

기본적으로 Property getter 메서드 명은 Property 자신의 이름과 동일 ( : Property foo일 경우 foo) 하지만 이 기본 설정을 내가 원하는 메서드명으로 변경 할 수 있습니다.

- setter=settername

Property setter 메서드 명은 setPropertyName: 입니다. ( : Property foo일 경우 setFoo:)

역시나 이 기본 설정을 내가 원하는 메서드명으로 변경 할 수 있습니다.

- readwrite (DEFAULT)

Property의 값을 읽고 쓸 수 있다는 것입니다. 이 설정은 기본 설정입니다.

- readonly

Property의 값을 단지 읽기만 할수 있다고 정의하는 속성입니다.

이 속성은 @implementation 블럭 안에서 오로지  getter 메서드만 필요할 경우에 사용합니다.

@synthesize 지시자를 사용하였을 경우에는 역시나 getter 메서드의 역할만을 하게 됩니다.

값을 대입 하려고 할 경우 에러를 출력하게 됩니다.

- assign (DEFAULT)

단순하게 값을 대입합니다. 기본설정입니다.

이전에 어떤 객체를 가리키고 있던 Property라면 이로 인해 해당 객체는 미아가 되어 메모리릭의 주범이 될 수 있습니다.

가비지콜렉터를 사용하지 않는다면 사용을 피해야 합니다.

- retain

이 것은 assign과 비슷하지만 조금 다릅니다.

이전에 가리키고 있던 객체가 있다면 해당 객체를 Release하여 메모리에서 제거 합니다.

- copy

객체를 바로 대입하지 않고 해당 객체의 복사 메서드를 Invoke호출합니다.

그리하여 다른 메모리 영역에 복사본을 만든 다음 그것을 반환하게 됩니다.

이전에 가리키고 있던 값은 Release 시킵니다.

- nonatomic

이 속성은 접근자 메서드가 Atomic 하지 않게 동작하게 합니다.

기본적으로 접근자는 Atomic하게 동작합니다.

Atomic 이라는 말은 멀티스레드 등으로 구성된 프로그램이 특정 접근자 메서드를 호출할때 서로 충돌이 나지 않도록 객체 레벨에서 Lock을 걸고 Property에 접근하게 됩니다.

이런 접근이 필요없다면 이 속성을 사용하여 Non-Atomic하게 동작하도록 만들어 주시는 것이 좋습니다.

- dealloc

객체가 제거 될때 소멸자로 dealloc 호출되는데 Property들이 자동으로 소거되지 않아

명시적으로 제거해 주셔야 합니다.

- (void)dealloc {
    [property release];
    [super dealloc];

}

 

n         재선언

서브클래스에서 슈퍼클래스의 프로퍼티의 재선언 가능

속성 선언을 다시 해줘야함

 

n         Markup and Deprecation

@property CGFloat x

AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4;

@property CGFloat y __attribute__((...));

 

 

 

 

Posted by 김반장78
,

u 프로토콜

n         정의

Protocols는 클래스 정의와 관련 없는 mothod선언 목록.

Protocols는 정의되어 있지 않은 객체에 메시지를 전달하고자 할 때 사용 가능

 

n         사용 범위

- 다른 사람들이 구현해야 할 mothod를 선언할 때

- 클래스는 숨긴 상태에서 object interface을 선어할 때

- 계층적으로 관련없는 클래스 간에 유사성을 가지게 할 때

 

n         Declaring Interfaces for Others to Implement

프로토콜로 선언된 메소드를 사용하려면, 프로토콜을 adopt(클래스가 프로토콜의 모든 메소드를 구현한다는 의미)하고, 그 메소드들을 구현.

- (void)mouseDown:(NSEvent *)theEvent;

- (void)mouseDragged:(NSEvent *)theEvent;

- (void)mouseUp:(NSEvent *)theEvent;

 

n         Methods for Others to Implement

- setAssistant:anObject

{

    assistant = anObject;

}

 

n         Declaring Interfaces for Anonymous Objects

id formatter = [receiver formattingService];

 

n         Non-Hierarchical Similarities

- (NSXMLElement *)XMLRepresentation;

- initFromXMLRepresentation:(NSXMLElement *)xmlString;

 

n         Formal Protocols (선언 방법)

@protocol 지시자를 사용

@protocol ProtocolName

method declarations

@end

 

n         XML을 이용한 protocol 표현이 가능

@protocol MyXMLSupport

- initFromXMLRepresentation:(NSXMLElement *)XMLElement;

- (NSXMLElement *)XMLRepresentation;

@end

 

n         주의점

- protocol은 클래스랑 연관지어 쓰는 것으로 단독으로 사용되지 않는다.

  따라서, protocol 이름은 자체의 namespace안에만 있게 되어 global하게 접근할 수 없다.

- protocol을 사용하려면 class가 그 protocol adopt해야 한다.

- protocol adopt할 클래스에서는 protocol이 선언된 헤더파일을 import 해야 한다.

 

n         Informal Protocols(Category 선언 내에 method를 선언한 것)

@interface NSObject ( MyXMLSupport )

- initFromXMLRepresentation:(NSXMLElement *)XMLElement;

- (NSXMLElement *)XMLRepresentation;

@end

              특징

              - informal protocol category와 선언방식은 똑같다.

차이점은 Catogory는 구현을 따로 카테고리로 만들어서 해야 하는 반면,

informal protocol은 구현을 클래스의method로 해 준다

 

n         Protocol Objects

런타임시 클래스는 class object method selector formal protocol protocol class

protocol object @protocol(protocol_name)지시자로 참조할 수 있다.

Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport);

 

n         Adoption a Protocol(adopt는 클래스가 protocol의 모든 mothod를 구현한다는 의미)

@interface ClassName : ItsSuperclass < protocol list >

@interface ClassName ( CategoryName ) < protocol list >

@interface Formatter : NSObject < Formatting, Prettifying >

 

n         Conforming to a Protocol

-클래스가 protocol adopt하고 있는지 알아보기 위해 conformsToProtocol:메시지를 object에 보낸다.

-respondsToSelector:는 한 method이 구현되어 있는지를 알려준다.

-isKindOfClass:는 클래스가 상속 계층구조안에 속하는지 여부를 알려준다.

if ( ! [receiver conformsToProtocol:@protocol(MyXMLSupport)]  ) {

    // Object does not conform to MyXMLSupport protocol

    // If you are expecting receiver to implement methods declared in the

    //  MyXMLSupport protocol, this is probably an error

}

 

n         Type Checking

protocol 타입선언 방법은 “type_name <protocol_name> 변수형태이다.

- (id <Formatting>)formattingService;

id <MyXMLSupport> anObject;

 

Formatter *anObject;

id <Formatting> anObject;
Formatter <Formatting> *anObject;

 

n         Protocols Within Protocols

@protocol ProtocolName < protocol list >

@protocol Paging < Formatting >

id <Paging> someObject;

 

if ( [anotherObject conformsToProtocol:@protocol(Paging)] )

 

n         상호참조 문제 해결

// A 선언

#import "B.h"

 

@protocol A

- foo:(id <B>)anObject;

@end

 

// B 선언

#import "A.h"

 

@protocol B

- bar:(id <A>)anObject;

@end

 

// A, B protocol이 상호 참조

@protocol B;

 

@protocol A

- foo:(id <B>)anObject;

@end

 

 

 


Posted by 김반장78
,

u 오브젝트의 메모리 할당과 초기화

n         객체생성시 요구사항

동적으로 새로운 객체를 메모리에 할당

새롭게 메모리에 할당된 객체에 적절한 값들로 초기화

작성예

id anObject = [SomeClass alloc];

[anObject init];

[anObject someOtherMessage];

간략화

id anObject = [[SomeClass alloc] init];

[anObject someOtherMessage];

반환값 체크

id anObject = [[SomeClass alloc] init];

if ( anObject )

[anObject someOtherMessage];

else

...

 

n         NSObject alloc, allocWithZone

NSObject는 모든 클래스가 상속받게되는 최상위 클래스 (자바의 Object클래스)

생성한 클래스와 클래스내의 인스턴스 변수들을 위한 메모리 공간 확보

확보한 메모리공간을 생성한 인스턴스변수가 가르키도록 지시(Pointer)

모든 인스턴스 변수들의 값을 0으로 세팅

 

n         초기화 메소드 구현

초기화 인스턴스 메소드의 명칭은 init로 시작

인자가 없는 초기화 메소드는 init:

인자가 있는 초기화 메소드는 initMethodName:

 

n         초기화 메소드 작성예

- 인자가 없는 경우

- (id)init {

self = [super init];

if (self) {

creationDate = [[NSDate alloc] init];

}

return self;

}

 

 

- 인자가 있는 경우

 

- (id)initWithImage:(NSImage *)anImage {

NSSize size = anImage.size;

NSRect frame = NSMakeRect(0.0, 0.0, size.width, size.height);

self = [super initWithFrame:frame];

If (self) {

image = [anImage retain];

}

return self;

}

 

n         메모리확보와 초기화의 결합

convenience constructors를 사용함으로서 메모리 자동해제(autorelease)를 적용

자동해제의 경우 직접해제를 할경우 크래시 발생

Posted by 김반장78
,

 

u 클래스 정의

n         Interface : 한 클래스의 메소드와 인스턴스 변수를 선언하고, 어느 수퍼클래스로부터 상속을 받는지를 기입

헤더 파일인 *.h 파일에 정의

 

n         Implementation : 실지로 클래스를 정의하는 부분

구현 파일인 *.m에 구현

 

n         해더 파일과 구현부를 나누는 이유

외부에서 볼때 구현부를 독립해 접근 불가능

 

n         작성 요령

가능하면 1:1로 작성 이름을 통일

 

n         인터페이스 작성 예

@interface ClassName : ItsSuperClass

{

instance variables declaration..

}

method declarations

@end

 

n         메소드 선언시 옵션

-

Instance method

+

Class method

              메소드 선언시 인스턴스와 클래스메소드 같은 이름으로 생성 가능

              메소드 이름과 인스턴스 변수도 같은 이름으로 생성 가능

 

n         메소드 선언 예

-선언

- (void) setWidth: (float) width height: (float) height;

-사용

id *myRect = [[Rectangle alloc] init];

[myRect setWidth:12.2 height:18.0];

-가변적 변수수를 가진 메소드 선언

- makeGroup:group, …;

 

n         interface import

interface import C #include와 동일하나, import가 똑 같은 것을 한번만 가져오는 것만 inclue와 다름.

 

n         implementation 작성예

@implementation ClassName : ItsSuperclass -> superclass 생략 가능

{

    instance variable declarations -> 생략 가능

}

method definitions

@end

              간단히 쓰면,

#import "ClassName.h"

 @implementation ClassName

method definitions

@end

 

n         다른 클래스 참조

인터페이스에 선언되지 않은 클래스를 사용할 때

상호참조의 문제를 해결하기 위해 @class 지시자를 사용.

@class Rectangle, Circle;

이것은 단지 컴파일러에 이것이 클래스 이름이라는 것만 알려주는 역할

 

n         인터페이스 특징

인터페이스파일은 클래스의 참조현황을 파악하기 쉽게함

인스턴스 개체를 따로 관리함으로서 보다 직관적인 OOP를 가능하게 함

 

n         instance변수들의 사용범위를 설명한 지시자

@private

instance변수의 범위를 그것이 선언된 class 한정한다.(상속불가)

@protected

instance변수의 범위를 선언되고, 상속된 class 한정한다. (상속가능)

@public

instance변수의 범위에 대한 제한을 없앤다. (상속가능)

 

n         instance변수 범위 지정의 이유

슈퍼클래스 변수와의 독립성을 유지함으로서 보다 완벽한 오브젝트화 가능

 

n         다른 객체에 속한 인스턴스 변수사용 예

선언구현부

@interface Sibling : NSObject

{

Sibling *twin;

int gender;

struct features *appearance;

}

참조구현부

- makeIdentification

{

if( !twin)

{

twin = [[Sibling alloc] init];

twin->gender = gender;

twin->appearance = appearance;

}

return twin;

}

 

 

영문 레퍼런스트를 정리하다가 갑자기 생겨난 쓸데없는 오기..ㅡ.ㅡ
도움 되려나~ 


Posted by 김반장78
,
import java.io.IOException;
import java.io.Writer;

import java.util.Stack;

import com.generationjava.io.WritingException;

/**
* Makes writing XML much much easier.
*
* @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
* @version 0.1
*/

public class XmlWriter {

    private Writer writer;      // underlying writer
    private Stack stack;        // of xml entity names
    private StringBuffer attrs; // current attribute string
    private boolean empty;      // is the current node empty
    private boolean closed;     // is the current node closed...

    /**
     * Create an XmlWriter on top of an existing java.io.Writer.
     */

    public XmlWriter(Writer writer) {
        this.writer = writer;
        this.closed = true;
        this.stack = new Stack();
    }

    /**
     * Begin to output an entity.
     *
     * @param String name of entity.
     */

    public XmlWriter writeEntity(String name) throws WritingException {
        try {
            closeOpeningTag();
            this.closed = false;
            this.writer.write("<");
            this.writer.write(name);
            stack.add(name);
            this.empty = true;
            return this;
        } catch (IOException ioe) {
            throw new XmlWritingException(ioe);
        }
    }

    // close off the opening tag
    private void closeOpeningTag() throws IOException {
        if (!this.closed) {
            writeAttributes();
            this.closed = true;
            this.writer.write(">");
        }
    }

    // write out all current attributes
    private void writeAttributes() throws IOException {
        if (this.attrs != null) {
            this.writer.write(this.attrs.toString());
            this.attrs.setLength(0);
            this.empty = false;
        }
    }

    /**
     * Write an attribute out for the current entity.
     * Any xml characters in the value are escaped.
     * Currently it does not actually throw the exception, but
     * the api is set that way for future changes.
     *
     * @param String name of attribute.
     * @param String value of attribute.
     */

    public XmlWriter writeAttribute(String attr, String value) throws WritingException {

        // maintain api
        if (false) throw new XmlWritingException();

        if (this.attrs == null) {
            this.attrs = new StringBuffer();
        }
        this.attrs.append(" ");
        this.attrs.append(attr);
        this.attrs.append("=\"");
        this.attrs.append(escapeXml(value));
        this.attrs.append("\"");
        return this;
    }

    /**
     * End the current entity. This will throw an exception
     * if it is called when there is not a currently open
     * entity.
     */

    public XmlWriter endEntity() throws WritingException {
        try {
            if(this.stack.empty()) {
                throw new XmlWritingException("Called endEntity too many times. ");
            }
            String name = (String)this.stack.pop();
            if (name != null) {
                if (this.empty) {
                    writeAttributes();
                    this.writer.write("/>");
                } else {
                    this.writer.write("</");
                    this.writer.write(name);
                    this.writer.write(">");
                }
                this.empty = false;
            }
            return this;
        } catch (IOException ioe) {
            throw new XmlWritingException(ioe);
        }
    }

    /**
     * Close this writer. It does not close the underlying
     * writer, but does throw an exception if there are
     * as yet unclosed tags.
     */

    public void close() throws WritingException {
        if(!this.stack.empty()) {
            throw new XmlWritingException("Tags are not all closed. "+
                "Possibly, "+this.stack.pop()+" is unclosed. ");
        }
    }

    /**
     * Output body text. Any xml characters are escaped.
     */

    public XmlWriter writeText(String text) throws WritingException {
        try {
            closeOpeningTag();
            this.empty = false;
            this.writer.write(escapeXml(text));
            return this;
        } catch (IOException ioe) {
            throw new XmlWritingException(ioe);
        }
    }

    // Static functions lifted from generationjava helper classes
    // to make the jar smaller.
   
    // from XmlW
    static public String escapeXml(String str) {
        str = replaceString(str,"&","&amp;");
        str = replaceString(str,"<","&lt;");
        str = replaceString(str,">","&gt;");
        str = replaceString(str,"\"","&quot;");
        str = replaceString(str,"'","&apos;");
        return str;
    } 

    // from StringW
    static public String replaceString(String text, String repl, String with) {
        return replaceString(text, repl, with, -1);
    } 
    /**
     * Replace a string with another string inside a larger string, for
     * the first n values of the search string.
     *
     * @param text String to do search and replace in
     * @param repl String to search for
     * @param with String to replace with
     * @param n    int    values to replace
     *
     * @return String with n values replacEd
     */

    static public String replaceString(String text, String repl, String with, int max) {
        if(text == null) {
            return null;
        }

        StringBuffer buffer = new StringBuffer(text.length());
        int start = 0;
        int end = 0;
        while( (end = text.indexOf(repl, start)) != -1 ) {
            buffer.append(text.substring(start, end)).append(with);
            start = end + repl.length();

            if(--max == 0) {
                break;
            }
        }
        buffer.append(text.substring(start));

        return buffer.toString();
    }             

    // Two example methods. They should output the same XML:
    // <person name="fred" age="12"><phone>425343</phone><bob/></person>
    static public void main(String[] args) throws WritingException {
        test1();
        test2();
    }
    static public void test1() throws WritingException {
        Writer writer = new java.io.StringWriter();
        XmlWriter xmlwriter = new XmlWriter(writer);
        xmlwriter.writeEntity("person").writeAttribute("name", "fred").writeAttribute("age", "12").writeEntity("phone").writeText("4254343").endEntity().writeEntity("bob").endEntity().endEntity();
        xmlwriter.close();
        System.err.println(writer.toString());
    }
    static public void test2() throws WritingException {
        Writer writer = new java.io.StringWriter();
        XmlWriter xmlwriter = new XmlWriter(writer);
        xmlwriter.writeEntity("person");
        xmlwriter.writeAttribute("name", "fred");
        xmlwriter.writeAttribute("age", "12");
        xmlwriter.writeEntity("phone");
        xmlwriter.writeText("4254343");
        xmlwriter.endEntity();
        xmlwriter.writeEntity("bob");
        xmlwriter.endEntity();
        xmlwriter.endEntity();
        xmlwriter.close();
        System.err.println(writer.toString());
    }
}

C#에는 있는데 왜 자바에는 없는거냐..ㅡ.ㅡ



Posted by 김반장78
,