본문 바로가기
교육/아이폰 앱 개발 기초 과정

[2010.7.11 (일)] 아이폰 앱 개발 기초 과정 (둘째날)

by 호군 2010. 7. 22.
반응형
 고준일 강사님의 개인적인 사정으로 토요일 강의가 일요일로 연기되었다. 그래서 두번째 강의는 일요일에 하게 되었다. 직장인 분들은 두번째 강의에서도 조금씩들 늦으셨다. 일요일인데도 쉬지 못하고 나름의(?) 노동을 하러 오시려니 힘든가보다. 강의 역시 조금 늦게 시작하게 되었다. 시작은 4장에서 나오는 간단한 키워드들에 대한 설명부터 하겠다.
 
1. 숙지사항과 키워드
 첫째날 강의에서 메모리관리를 잘해야 한다고 했다. 그래서 한 가지 규칙만 지킨다면 메모리를 완벽하게 관리 할 수 있다. "오브젝트는 alloc 한 곳에서 책임지고 release 한다."  이 규칙만 지킨다면 메모리 관리로 앱스토어에 올리시에 Apple에서 거절 당하지는 않을 것이다.
 Object-C에 #import와 @class가 있다. #import는 #include와 동일한 기능을 수행하지만 중복 참조를 방지해준다. @class는 import하지 않고 해당 클래스가 있다고 알려준다. C++을 했더라면 쉽게 이해 할 것이라고 생각된다.
 Object-C에서는 프라퍼티(property)가 있다. 인스턴트 오브젝트에서 맴버변수를 외부에서 접근하기 위해서는 접근가능한 메소드가 필요하다. 하지만 이 메소드를 만드는 일은 단순한 반복 작업에 지나지 않기 때문에 property를 이용해서 자동으로 getter와 setter 메소드를 생성하게 한다. 이 키워드는 헤더파일에서 사용 되고, setter는 '맴버변수' 그대로 사용하고, getter는 'get멤버변수'로 사용한다. synthesize라는 키워드도 있다. 이 키워드는 구현파일에서 사용되고, property와 짝을 이루어서 사용되어진다.

                                        - 프로퍼티의 어트리뷰트 설정 -
 assign int, float, BOOL과 같은 값을 다루는 방식
 retain 넘어온 오브젝트의 리테인 카운트를 1증가시켜 보관하며 이전 값은 release된다. 코코아 오브젝트는 대부분 retain방식을 사용한다.
 copy 넘어온 매개변수를 복사해서 보관하며 이전 값은 release한다. 넘어온 오브젝트는 NSCopy 프로토콜을 준수해야 한다.
 nonatomic 쓰레드에 안전하지 않도록 한다.
 atomic 쓰레드에 안전하도록 한다. property는 기본적으로  atomic으로 설정되어 있다.
 readwrite   읽고 쓸 수 있도록 setter와 getter가 제공한다.
 readonly 읽기만 할 수 있도록  getter만 제공한다.



2. 코코아 터치의 3가지 컬렉션
 NSSet 가장 단순한 컬렉션으로 순서를 가지지 않는 오브젝트들의 집합이다. 순사가 없으므로 이미 세트 내에 존재하는 오브젝트를 더하면 추가되지 않는다. 그래서 특정 오브젝트로 접근 할 수 있는 방법이 없다.
 NSArray 배열처럼 순서를 가지는 오브젝트의 집합이다. 오브젝트를 여러 번 추가해도 각각의 순서를 가지면 추가되고, 접근은 인덱스 값을 이용해서 접근 할 수 있다.
 NSDictionnary 이름을 가진 오브젝트들의 집합니다. 오브젝트를 추가 할 때 키값을 지정하기 때문에 그 키값을 이용해서 특정 오브젝트에 접근 할 수 있다.
 이 컬렉션들을 상속 받은 서브클래스들이 있다. NSMutableSet, NSMutableArray, NSMutableDictionary가 그 서브 클래스이다.



3. 노티피케이션 
 노티피케이션은 알림, 통지라는 뜻이다. 이 방식을 가장 이해하기 쉬운 예는 모집공고 이다.

 노티피케이션은 위의 그림과 매우 유사하다. 어플리케이션 내에 하나의 오브젝트로서 노티피케이션 센터가 있다. 오브젝트가 어느 곳에서든 접근 할 수 있고, 동일한 노티피케이션 센터로 접근하게 된다. 여기서 노티피케이션 센터는 모집공고 게시판이라고 가정한다면 특정 모집공고에 관심이 있는 사람들이 모집공고 게시판을 주시 할 것이다. 인력이 필요한 사람은 모집공고 게시판에 모집공고를 등록 할 것이다. 그럼 그 모집공고에 관심이 있는 사람들은 반응을 하게된다. 당연히 늦게 그 공고를 보는 사람은 기회조차 없을 것이다. 이젠 노티피게이션에 대해서 이해하리라 본다.

 - 코드
Observer 등록
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uiUpdate:)
 name:@"CandleDidChanged" object:nil]; 
Post 알림
[[NSNotificationCenter defaultCenter] postNotificationName:@CandleDidChanged"
 object:self userInfo:nil];
 


4. Key-Value Observing(KVC)
 키-벨류 코딩은 키를 이용해서 값을 등록하고, 지정된 키를 이용해서 값을 읽어온다. 
읽기/쓰기는 -setValue:forKey: 와 -valueForKey: 메소드를 이용해서 수행 할 수 있다. 조금 쉽게 이해하기 위해 엑세스 방식 중 3가지 방법을 예로 하여 알아보도록 한다.

- 코드
메소드 방식
BOOL candleStateValue = [myCandle candleState];
[myCandle setCandleState:!candleStateValue];
프로퍼티 방식
BOOL candleStateValue = myCandle.candleState
myCandle.candleState = !candleStateValue;
키-벨류 코딩 방식
BOOL candleStateValue = [myCandle valueForKey:@"candleState"];
[myCandle setValue:!candleStateValue forKey:@"candleState"];
 위의 예제 코드를 보면 키-벨류 코딩방식을 사용 할 수 있을 것이다. 하지만 위의 예제로는 특별한 기능을 찾지 못 할 것이다. 프로퍼티로도 충분히 할 수 있는 역활이기 때문이다. 키-벨류 코딩은 키-벨류 옵저빙과 함께 사용 해야 그 활용을 알 수 있다고 한다.
(책을 읽고는 그리 큰 장점은 못 느꼈다. property로 명시적으로 어떻게 사용 할지 결정 한 후 접근 하는 방법이 더 나을 것 같다는 생각이 든다)



5. Key-Value Observing(KVC)
 키-벨류 옵저빙 오브젝트의 특정 키에 대한 값이 변했는지 관찰하는 기능이다. 값이 변했는지 관찰하기 위해서는 -addObserver:forKeyPath:options:context: 메소드로 대상에 대한 감시자를 등록하고, -observeValueForKeyPath:ofObject:change:context: 메소드를 감시자에서 구현해줘야 한다.

- 코드
옵저버 등록
[myCandle addObserver:self forKeyPath:@"candleState" option:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil] 
[self addObserver:self forKeyPath:@"myCandle.candleState" option:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil] 
 옵저버 등록은 위의 예제처럼 -addObserver:forkeyPath:option:context: 메소드를 이용하면 할 수 있다. 붉은 글씨를 보면 메소드를 호출하는 오브젝트에 따라서 forKeyPath의 경로가 달라지는 것을 볼 수 있다. 그리고 option에 대한 설명은 아래 표를 보길 바란다.

option 종류
NSKeyValueObservingOptionNew:
 감시하는 값의 변경된 새 값이 부가정보에 넘어온다. (모든 타입에 적용되지 않음)
NSKeyValueObservingOptionOld:
 감시하는 값의 변경된 이전 값이 부가정보에 넘어온다. (모든 타입에 적용되지 않음)
NSKeyValueObservingOptionInitial:
 즉시 오브젝트값의 변화를 감시하기 시작한다.(-addObserver:forkeyPath:option:context: 메소드가 끝나기도 전에 감시를 시작)
NSKeyValueObservingOptionPrior:
 값이 변할 경우 보통 한번의 통지를 보내는 반면 이 옵션이 설정되면 변경의 전후로 통지를 한다.

옵저버를 등록했다면, 값이 변경될 경우 동작해야할  메소드를 구현 해야 할 것이다. 그래서 감시자에 등록된 오브젝트에는 -observeValueForKeyPath:ofObject:change:context: 메소드가 구현되어 있어야 한다. 응용하기 위한 기초 소스를 보면 알 수 있을 것이라고 생각한다.

- 코드
 옵저버 구현 메소드
 - (void)observeValueForKeyPath:(NSString)keypath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
    if([keyPath isEqualTostring:@"candleState"])
    {
        //Do something
    }
}



6. 테이블 뷰
 테이블 뷰는 다루기 가장 어려운 화면 구성요소이다. 아래 그림을 보면 테이블 뷰가 어떤 UI 컨트롤인지 알 수 있다.

 (1) 테이블 뷰 구성
  테이블 뷰에는 테이블 헤더(header)와 테이블 푸터(footer)를 필요에 따라 붙일 수 있고, 1개 이상의 섹션(Section)으로 구성되어져 있다. 섹션은 섹션 헤더(header)와 섹션 푸터(footer)로 구성되어져 있고, 1개 이상의 셀로 구성되어져있다. 아래 그림은 하나의 섹션에 대한 그림이다.

  셀(Cell)은 ImageView, TextLabel, DetailTextLabel, AccessoryView 로 구성되어 있다. 아래 그림을 보면 각 위치를 알 수 있다.
 
AccessoryView의 종류
Disclosure Indicator Detail Indicator
 - View 오브젝트
 - 테이블 뷰 셀 영역을 선택하면 보다 자세한 
    단계의 뷰가 밀려들어 올 것을 알려줌
 - 뷰의 계층이 데이터 계층에 대응하도록
    설계되어있음
 - Button 오브젝트
 - 테이블 뷰 셀 영역을 선택하면 셀의 내용에
    대한 자세한 정보를 담고 있는 뷰가 밀려들
    어올 것을 알려줌
 - 데이터 계층과 상관없이 셀에 나타난 오브
    젝트에 대한 자세한 정보가 나타남

 (2) 테이블 뷰 동작 방식
 
  - 코드
 - (NSInteger)numberOfSectionInTableView:(UITableView*)TableView
 테이블 뷰에 몇개의 섹션(Section)이 있는지를 리턴한다. 보통 1을 리턴한다.
 - (NSInteger)tableView:(UITableView*)TableView
    numberOfRowsInSection:(NSInteger)section
 각 섹션별로 몇개의 로우(Row)를 준비할지를 리턴한다.
 - (UITableViewCell*)tableView:(UITableView*)TableView cellForRowAtIndexPath:(NSindexPath*)indexPath
 각각의 섹션(Section)에 있는 로우(Row)자리에 들어갈 테이블 셀(Cell)을 구성해서 리턴한다.

(3) 재사용 큐
 테이블 뷰는 많은 양의 데이터를 몇가지 일정한 형태로 정리해서 보여주는 뷰이다. 그러므로 테이블 뷰가 표시하는 뷰는 내용만 다를 뿐 모양은 반복된다. 그래서 반복되는 뷰를 얼마나 잘 관리하느냐가 테이블 뷰의 성능을 좌우하는 요소가 된다.
 테이블 뷰에는 재사용 큐를 사용하여 효율적으로 메모리를 사용한다. 재사용 큐라고 부르는 이 버퍼는 화면 밖으로 사라지는 테이블 셀을 임시로 지니고 있는다. 그와 동시에 새롭게 추가되는 셀의 형태가 재사용 큐에 있는 셀의 형태와 동일하다면 새로운 셀을 만들지 않고, 재사용 큐에 있는 셀에 값을 바꿔서 테이블 뷰에 넣어준다. 아래 그림을 보면 좀 더 알기 쉬울꺼라고 생각된다.  




7. 네비게이션
 아이폰에서 네비게이션은 아이폰의 화면이 좌/우로 밀려나거나 밀려들어오는 것을 말한다. 아이폰은 화면이 작기 때문에 모든 것을 하나의 화면에 보여주기가 힘들다. 그래서 작은 화면을 효율적으로 사용하기위해서 네이게이션 기능을 사용한다.  
 뷰가 움직이는 방향에 따라 push, pop, modal 로 불러진다. 뷰가 오른쪽에서 밀고 들어오면 push 방식이고, 오른쪽으로 밀려 들어왔던 뷰가 밀려 나가면 pop 방식이다. 그리고 뷰가 아래에서 위로 밀고 올라가면 modal 방식이다.
네비게이션을 사용 할 때 알아야 할 클래스에 대해서 알아보도록 한다.
 NavigationController 네이게이션 자체를 관리하는 컨트롤 클래스이다. 뷰 컨트롤러를 바꾸어서 화면은 전환하는 역활을 한다.
 UIViewController 화면 전체 크기의 뷰를 관리하는 클래스이다.
실제 뷰가 바뀌는 효과는 뷰 컨트롤러가 바뀌는 것이다.
 UINavigationBar UIView의 서브클래스로서 화면 상단에 위치한 바이다. 네비게이션 스택을 운용하며 스택 안의 네이게이션 아이템에 대해 접근할 수 있다.
 UINavigationItem  네이게이션 스택 위에 올라간느 아이템들을 가지고 있는 오브젝트이다. 시작적인 정보를 가지고 있지 않아 보이지 않으며, 스택 안에서 밀려나가고 밀고 들어오는 오브젝트들의 정보를 담고 있다. 타이틀뷰와 왼쪽 바 버튼 아이템, 오른쪽 바 버튼 아이템을 가지고 있다.
 UIBarButtonItem 사용자의 터치에 반응해 액션 메소드를 실행시키는 버튼 아이템이다.
 
 위의 클래스들이 어떻게 사용되는 그림으로 보도록 한다.

 네이게이션 컨트롤러는 뷰 컨트롤러를 바꾸면서 화면을 전환한다. 이때 네이게이션바 위에 네이게이션 아이템들이 올라가게 된다. 그래서 사용자에게 보여지는 화면은 아래와 같은 화면을 보여주게 된다. 
 
위의 그림을 보면 3가지 아이템(왼쪽 바버튼 아이템, 타이틀, 오른쪽 바버튼 아이템)이 있는데, 그 중 Title은 꼭 입력해야 한다.왼쪽 바버튼 아이템과 오른쪽 바 버튼 아이템의 이름은 전의 뷰와 다음 뷰의 타이틀을 보고 결정되기 때문이다. 만약 Title을 입력하지 않으면, 이전 뷰와 다음 뷰의 Next와 Prev가 보이지 않을 것이다.



8. Tip
◎ UIApplication은 시스템과 근접해 있다. 이 UIApplication이 어플리케이션 동작에 필요한 초기화 작업과 AppDelegate를 호출하기 때문에 변경하기 위해서는 구조를 잘 알아야 한다. 만약 구조를 모른다면 함부로 건들지 않는다.
◎ UIView는 Mac의 UIView가 아이폰에 돌리기 무거워서 가볍게 만들어진 View들의 상위 클래스이다. UIView는 단순 화면에 표시 기능과 색상을 설정하는 기능정도밖에없다. UIImageView는 UIView를 상속받은 클래스이고, 이미지 파일만 보여주는 정도의 기능을 갖고 있다.
◎ 할당과 해제 메소드의 연관
    - alloc ↔ dealloc
    - retain ↔ release
    alloc은 참조가 1인 객체를 할당 시키고, dealloc은 참조가 0이 되어 객체를 파괴한다.
    retain은 참조를 1 증가 시키고 release는 참조를 1 감소 시킨다. 
◎ 기본적으로 iPhone 내장된 18가지의 App 중 몇가지를 이용 할 수 있다.
    - Photo(사진), Contacts(주소록), Calendar(일정), iPod(음악, 비디오)
◎ 애플 푸시 알림 서비스(APNS, Apple Push Notification Service)
    - iOS3 에서는 멀티스레드를 사용 할 수 없었다. 그래서 어플들이 동시에 실행이 불가능 하다.  하지만 애플의 푸시 서비스를 이용한다면 다른 앱을 사용하는 중에 해당 앱을 동작시킬 수 있다.






반응형