Saturday, April 2, 2011

iphone 개발 수업 4주차-2

4/2
<frame work>
frameworks 는 라이브러리다. 프레임 워크를 사용하려면 이를 프로젝트에 add 해야 한다(라이브라러파일을 같은 폴더에 넣어야 한다).


<UITable View 다시 보기>
UITableViewDataSource; 내용관리, 관련 메소드는 교재 159p
UITableViewDelegate; 이벤트 관리(셀선택, 셀 내용편집 및 삭제), 관련 메소드는 교재 167p


UIApplication 객체가 이벤트를 감시하고 있는데 화면의 셀을 선택하면 UIApplication 객체가 UITableViewDelegate 객체의 didSelectRowAtIndexPath 메소드를 호출한다. 이때 넘겨주는 인자가 NSIndexPath 객체, 이 객체는 속성으로 section(선택된 센션 인덱스)와 row(선택줄의 인덱스)를 가지고 있다.


프로토콜은 자바의 인터페이스와 동일, 속성은 없고 구현을 하지 않은 메소드만 존재, 대표적으로 UItableDelegate와 DataSource.




<ViewController 하나 더 만들기>
navigation based application 을 만들면 하나의 ViewController 만 생기는데 하나의 화면을 더 만들고 싶으면 classes에서 우클릭해서 add , new File, 거기서 UIViewController subclass를 선택(UIViewController 클래스를 상속받는 클래스). 옵션도 선택(iPad용이냐, UITableViewController 를 상속 받을 것이냐, xib 즉 xml 파일을 만들 것이냐).
그리고 UInavigation Bar 에 right 버튼을 생성하거나 back 버튼 대신 다른걸 만들고 싶을 때 Bar Button Item 클래스(버튼 클래스와 비슷한데 다만 단순화 시킨것, 곧 클릭했을때의 이벤트만 메소드로 가지고 있음)를 가져오는데 interface builder에다가 navigation bar 위치에 넣을려면 안되고 xib 에다가 넣는다. 이것들을 UIViewController의 UIBarButtonItem 클래스의 변수에 연결시키고 또 이것이 선택되어졌을 때(이벤트가 발생했을때) 진행되어야 할 메소드를 연결시킨다.


UIViewController 의 initWithNibName 메소드(이때 인자가 xib 파일의 이름과 그 파일의 경로(bundle의 인자, nil이면 현재 경로))를 사용하면 xib 파일과 객체를 연결시켜준다.  




<셀의 UI 바꾸기>
xib 를 하나 생성하는데 user interface 에서 View xib를 선택. 그러면 View 에 관한 interface가 생기는데 이걸 생성하려는게 아니기 때문에 이 View 를 지운다음에 Table View Cell 을 라이브러리에서 xib로 가져온다. 그런다음에 그 UI, 즉 Table View Cell에 넣을 UI 를 라이브러리에서 가져다가 Table View Cell 안에 드레그 한다. 그리고 이것들(Table View Cell 안의 다른 UI들, 즉 UIImage나 UILabel들)의 객체를 리턴 받아야 하는데 이때 사용하는 것이 tag. 그 다음에 이 변형된 table View cell을 갖을 delegate(여기서는 RootViewController)로 가서 cellForRowAtIndexPath메소드를 바꿔준다. NSArray * topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"PhotoTableCell" owner:self options:nil] ; 이렇게 하면 topLevelObjects에는 DOM(Document Object Model) 형식의 객체가 리턴된다. 이 DOM에는 PhotoTableCell.xib의 객체들이 트리 형태로 들어 있게 된다. 이 DOM 객체를 가르키는 topLevelObjects는 index로 DOM 안의 객체(Table View Cell, UIImage, UILabel)로 접근하거나 아니면 앞에서의 tag로 접근 가능하다.


결론은 특정 UI를 바꿀려면 UI 안에 UI를 넣은 xib 파일(그러니까 변형된 UI)을 만들고 NSBundle mainBundle로 가져온다.
---------------------------------------------------------------------------------------------


<메모리 관리>
저장 장치, 그러니까 하드디스크에 저장된 것은 클래스, 이것을 메모리에 올리면 객체가 된다(메모리에 올려야 작동). 메모리에 올리려면 사용하는 메서드가 alloc 제거하려면 사용하는 메서드가 dealloc 이는 둘다 NSObejct클래스가 가지고 있는 메소들이다. 그런데 dealloc은 잘 사용하지 않음(다른 변수가 참조 할때 dealloc 해서 메모리에서 지우면 다른 변수가 참조시 에러가 나기 때문). 그래서 이때 사용하는 것이 NSObject의 retainCount라는 속성. retainCount는 몇개의 포인터에서 이 객체를 참조하는가 하는 카운트 값을 가지고 있다. 초기값, 그러니까 처음 생성되면 1을 갖는다. 이 retainCount 값은 NSArray, NSSet, NSDictionary, UITableView등에 삽입시 1 증가.  또 retain 메소드 호출시 1 증가. 반대로 NSArray등에서 빼거나 release 메소드를 호출하면 1 감소. retainCount가 0이 되면 자동으로 그 객체는 자동으로 삭제된다.


A *a = [[A alloc] init]; 이렇게 하면 반드시 release를 해야 한다.
A *a = [[[A alloc]init] autorelease]; 구현된 메서드 init()이 끝나면 자동으로 [a release]를 호출.


autorelease는 문제점이 하나 있는데 특정 메소드에서 객체를 생성해서 그 객체를 return 할때 autorelease를 하면 객체를 리턴받을때 삭제되어 있는 상태기 때문에 에러가 난다. 그래서 이럴때 autorelease를 사용하면 반드시 retain 메소드를 호출해야 한다. 


즉 상황에 따라 autorelease 를 사용하는 것이 좋을때도 있고 나쁠 때도 있는데 한 메소드 안에서 잠시 사용하는 것은 autorelease를 사용하는 것이 좋다.


autorelease모드인 경우 : 1.객체 생성이 autorelease 명시시, 2. alloc을 안해준 객체 생성, 예를 들어 [NSDictionary initWithArray:array]
-------------------------------------------------------------------------------------------------


<데이터 저장>
1.파일에 저장: NSFileManager사용
2.메모리의 저장 : 어플 종료시 내용 사라짐
3.코어 데이터 : sqlite 사용. 저장, 로드, 검색이 가능. ORM(객체 지향 DB); 직접 query를 이용하는것이 아니라 객체를 통해서 query를 던지다.


NSPersistentStoreCoordinator ; 파일(바이너리)을 읽어서 내용을 꺼내줌, 즉 파일에 있는 정보를  NSPersistentStoreCoordinator에 query를 던지면 관련 entity를 NSManagedObjectContext에 NSManagedObject 객체 형태로 메모리에 올린다. 이때 query를 던지는 클래스는 NSFetchRequest.