본문 바로가기
  • SDXL 1.0 + 한복 LoRA
  • SDXL 1.0 + 한복 LoRA
Development/iPhone

[옛 글] SimpleSectionedTableView - Region, TimeZoneWrapper

by 마즈다 2013. 7. 12.
반응형

최초 작성일 : 2010/04/10 16:06 



SimpleSectionedTableView 추가된 내용  하나는 Model 클래스가 추가되었다는점이다.

Model Object 데이터를 캡슐화 하는 핵심적인 역할을 하고 있으며  데이터 접근할 있는

접근자를 제공한다모델 클래스들은 전통적인 행동 방식(getter 이용하는 ?) 내에서 값을 추가할  있다.

Region 클래스는 시스템으로부터 시스템이 알고있는 TimeZone 정보를 가져와
지역 이름을 추출하여 Region 인스턴스들이 담긴 regions 배열을 만들고
regions 배열에 담긴 각각의 Region 인스턴스에 있는 TimeZoneWrappers라는 
인스턴스 배열 변수에 TimeZoneWrapper 클래스의 인스턴스를 설정하여
넣는다.

전체적인 구조는 Region 클래스는 지역 이름을 담당하여 지역 이름의 배열을 만들고
TimeZoneWrapper 클래스는 Time Zone 관련 데이터를 담당하여 각각의
Region 클래스의 인스턴스 안에 역시 배열로 들어간다.

regions[0]
timeZoneWrappers[0]
timeZoneWrappers[1]
timeZoneWrappers[2]
...
regions[1]
timeZoneWrappers[0]
timeZoneWrappers[1]
...
regions[2]
timeZoneWrappers[0]
timeZoneWrappers[1]
...
...

regions[0], regions[1], regions[2]는 각각 Region 클래스의 인스턴스이고
timeZoneWrappers[i]는 각각 TimeZoneWrapper 클래스의 인스턴스들이다.


Region.h


@interface Region : NSObject {

NSString *name;

NSMutableArray *timeZoneWrappers;

}

//@property 이용하여 getter setter 선언 자동화

//@property 속성으로 copy 지정된 경우얕은 복사가 일어난다.

//얕은 복사는 원본 데이터가 담겨있는 메모리의 주소만을 복사하여  변수에

//넘기고 원본의 주소는 release 되는 형태로 복사가 이루어진다고 하여 실제로

//데이터가 2개가 되는 것은 아니다.

@property (nonatomiccopy) NSString *name;

@property (nonatomicretain) NSMutableArray *timeZoneWrappers;

//클래스 메서드의 선언앞에 + 기호로 시작하는 메서드는 클래스 메서드로

//주로 클래스의 인스턴스를 생성하거나 글로벌 클래스 데이터에 접근하는 역할을 하며

//java static 선언과 유사하다고 생각하면 된다.

//반대로 -기호로 시작하는 메서드는 인스턴스 메서드이며 인스턴스 메서드는 클래스의

//인스턴스와  생명 주기를 함께 한다.

+ (NSArray *)knownRegions;

@end




Region.m

지역과 지역별 Time Zone 데이터를 설정하고 정렬하는 Model 클래스


//헤더파일 임포트

#import "Region.h"

#import "TimeZoneWrapper.h"

//카테고리 선언 : Private라는 이름으로 Region 클래스에 카테고리를 선언함

@interface Region (Private)

- (id)initWithName:(NSString *)regionName;

//setUpKnownRegions 메서드는 클래스 메서드로 선언도어 있으므로 인스턴스 생성 없이

//클래스로부터 바로 호출할  있다.

+ (void)setUpKnownRegions;

- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper;

- (void)sortTimeZones;

@end


@implementation Region

//@property 키워드와 함께 name, timeZoneWrapper 대한 getter setter 자동으로 구현한다.

@synthesize name, timeZoneWrappers;

//클래스 메서드인 setUpKnownRegions 통해 값을 설정할  있도록 static으로 선언된 변수

static NSMutableArray *knownRegions = nil;

//클래스 메서드인 knownRegions 내부에서 카테고리를 통해 선언된 클래스 메서드인

//setUpKnownRegions 메서드를 호출한다  사용된 self Region 클래스를 의미한다.

+ (NSArray *)knownRegions {

if (knownRegions == nil) {

[self setUpKnownRegions];

}

return knownRegions;

}

#pragma mark -

#pragma mark Memory management.

//메모리 해제...

- (void)dealloc {

//copy 생성된 것에 대한 메모리 해제

[name release];

[timeZoneWrappers release];

[super dealloc];

}

#pragma mark -

#pragma mark Private methods for setting up the regions.

//카테고리를 통해 선언된 메서드의 구현인자로 받은 regionName 통해 호출되는 copy

//NSObject 구현되어있으며  copy 메서드는 NSCopying 적용된 subclass에서

//copyWithZone 함수를 호출하는 방식으로 동작한다. NSCopying 프로토콜은 NSString

//적용 되어 있다.

//copy 새로운 인스턴스 변수에 원본의 주소값을 복사한  retain count 1 증가 시키므로

//release 통해 메모리 해제를 해주어야 한다.  

- (id)initWithName:(NSString *)regionName {

if (self = [super init]) {

name = [regionName copy];

timeZoneWrappers = [[NSMutableArray allocinit];

}

return self;

}

//클래스 메서드인 setUpKnownRegions 구현

+ (void)setUpKnownRegions {

//시스템으로부터 확인된 TimeZone 이름 배열을 가져오고  배열의 크기와 동일하게

//변경 가능한 배열인 regions 만든다.

NSArray *knownTimeZoneNames = [NSTimeZone knownTimeZoneNames];

NSMutableArray *regions = [[NSMutableArray allocinitWithCapacity:[knownTimeZoneNames count]];

//knownTimeZoneNames 크기만큼 루프를 돌면서 배열  하나 하나를 timeZoneName 넣는다.

for (NSString *timeZoneName in knownTimeZoneNames) {

//knownTimeZoneNames로부터 받은 문자열을 "/" 구분자로 나누어

//배열 nameComponents 담는다.

NSArray *nameComponents = [timeZoneName componentsSeparatedByString:@"/"];

//배열 nameComponents 0번째 값을 가져와 regionName 할당한다.

NSString *regionName = [nameComponents objectAtIndex:0];

// Get the region  with the region name, or create it if it doesn't exist.

Region *region = nil;

//for문을 통해 regions 배열의  하나 하나를 Region 인스턴스인 aRegion 할당한다.

for (Region *aRegion in regions) {

//regions로부터 받아온 값의 name 속성이 regionName 같다면

//region aRegion 할당하고 루프를 빠져나옴

if ([aRegion.name isEqualToString:regionName]) {

region = aRegion;

break;

}

}

//만일 name 일치하는 경우가 없다면 regionName 사용하여 새로운 region 만들어

//regions 추가한다.

if (region == nil) {

region = [[Region allocinitWithName:regionName];

[regions addObject:region];

[region release];

}

//timeZoneName 사용하여 NSTimeZone 인스턴스인 timeZone 생성하고

NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];

//생성된 timeZone timeZoneName 배열로 만든 nameComponents 인자로

//TimeZoneWrapper 인스턴스를 생성한다.

TimeZoneWrapper *timeZoneWrapper = [[TimeZoneWrapper allocinitWithTimeZone:timeZonenameComponents:nameComponents];

//생성된 timeZoneWrapper NSMutableArray timeZoneWrappers 넣는다.

[region addTimeZoneWrapper:timeZoneWrapper];

//alloc으로 생성했으므로 메모리 해제

[timeZoneWrapper release];

}

// Now sort the time zones by name

//카테고리를 통해 추가된 함수를 호출하여 이름순으로 정렬

for (Region *aRegion in regions) {

[aRegion sortTimeZones];

}

// Sort the regions

//지역(region) 정렬

//"name" 속성을 기준으로 오름차순 정렬을  것임을 NSSortDescriptor클래스의 인스턴스를 통해 설정

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor allocinitWithKey:@"name" ascending:YES];

//initWithObjects 인자로 넘겨받은 C 배열로부터 count 인자로 넘겨받은 수만큼의(여기서는 1객체를

//가져와 새롭게 배열로 할당한다.

NSArray *sortDescriptors = [[NSArray allocinitWithObjects:&sortDescriptor count:1];

//sortDescriptors 이용해 실제로 배열을 정렬한다.

[regions sortUsingDescriptors:sortDescriptors];

[sortDescriptor release];

[sortDescriptors release];

knownRegions = regions;

}

//인자로 받은 timeZoneWrapper NSMutableArray timeZoneWrappers 넣는다.

- (void)addTimeZoneWrapper:(TimeZoneWrapper *)timeZoneWrapper {

[timeZoneWrappers addObject:timeZoneWrapper];

}

- (void)sortTimeZones {

// Sort the time zones by name

//time zones 정렬 - 상세 과정은 위의 지역 정렬 참조

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor allocinitWithKey:@"localeName"ascending:YES];

NSArray *sortDescriptors = [[NSArray allocinitWithObjects:&sortDescriptor count:1];

[timeZoneWrappers sortUsingDescriptors:sortDescriptors];

[sortDescriptor release];

[sortDescriptors release];

}

@end




TimeZoneWrapper.h


//TimeZoneWrapper 인터페이스

@interface TimeZoneWrapper : NSObject {

NSString *localeName;

NSTimeZone *timeZone;

}

//지역 이름과 time zone 설정을 위한 인스턴스 변수 선언  getter/setter 선언

@property (nonatomiccopy) NSString *localeName;

@property (nonatomicretain) NSTimeZone *timeZone;

//초기화를 위한 인스턴스 메서드 선언

- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray *)nameComponents;

@end



TimeZoneWrapper.m


#import "TimeZoneWrapper.h"



@implementation TimeZoneWrapper

//인스턴스 변수들에 대한 getter/setter 구현

@synthesize localeName, timeZone;


- (id)initWithTimeZone:(NSTimeZone *)aTimeZone nameComponents:(NSArray*)nameComponents {

if (self = [super init]) {

//retain 통해 인스턴스 할당. retain 인스턴스 자신을 반환하며 참조 카운트를 1 증가 시킨다.

//인스턴스의 사용이 종료되기 전까지 메모리에서 해제하는 것을 막는다따라서 사용 후에 반드시

//적절한 시점에서 release 해주어야 한다.

timeZone = [aTimeZone retain];

NSString *name = nil;

//인자로 넘어온 nameComponents 배열의 크기가 2인경우 nameComponents 

//인덱스 1 있는 값을 retain 통해 name으로 할당한다.

if ([nameComponents count] == 2) {

name = [[nameComponents objectAtIndex:1retain];

}

else {

//그렇지 않은 경우 인덱스 2 값과 인덱스 1 값을 조합하여 name 할당한다.

name = [[NSString allocinitWithFormat:@"%@ (%@)", [nameComponentsobjectAtIndex:2], [nameComponents objectAtIndex:1]];

}

//name 문자열에서 "_" 모두 " " 바꾸어 localeName 할당한다.

localeName = [[name stringByReplacingOccurrencesOfString:@"_"withString:@" "retain];

[name release];

}

return self;

}


//메모리 해제

- (void)dealloc {

[localeName release];

[timeZone release];

[super dealloc];

}



@end


반응형