[Objective-C] Foundation 프레임워크의 중요 클래스 - NSDictionary, NSValue, NSNumber, NSURL |
9.5. 사전 클래스
* 9.5.1. 사전 객체 개요
-
키와 값 짝을 엔트리(entry)라고 부른다.
키도 값도 객체를 지정하는데 키에는 보통 문자열을 지정하는 편이다.
-
키는 그 사전 객체 속에서는 유니크이어야만 한다.
메서드 isEqual: 로 비교해서 같다고 평가되는 키를 가진 엔트리가 여러 개 있어선 안 된다.
키는 nil 도 안 된다.
-
값 객체에는 nil 이외의 임의의 객체를 지정할 수 있다.
숫자값과 좌표 등 자료형을 사전에 포함하고 싶을 때는 나중에 오는 NSNumber, NSValue 를 사용해야 한다.
또한 비어있는 것을 나타내고 싶을 때는 NSNull 을 사용할 수 있다.
-
기본적으로 키로 지정한 객체는 복사, 즉 복제가 만들어져서 사전에 저장된다.
** 9.5.2. NSDictionary
-
NSDictionary 는 클래스 클러스터로 제공되므로 NSDictionary 가 인스턴스 직접 클래스가 아니라는 것, 일반적인 방법으로는 서브 클래스를 만들 수 없다는 것에 주의해야 한다.
** 사전 객체 초기화, 작성
-
+ (id) dictionary
+ (id) dictionaryWithObject: (id) anObject forKey: (id) aKey
- (id) initWithObjects: (NSArray*) objects forKeys: (NSArray*) keys
편의생성자 : dictionaryWithObjects:forKeys:
- (id) initWithObjects: (id *) objects forKeys: (id *) keys count: (NSUInteger) count
편의 생성자 :dictionaryWithObjects:forKeys:count:
- (id) initWithObjectsAndKeys: (id) object, (id) key, ...
object 와 key 가 교대로 나온다.
편의생성자 : dictionaryWithObjectsAndKeys:
- (id) initWithDictionary: (NSDictionary*) otherDictionary
편의 생성자 : dictionaryWithDictionary:
** 사전 접근
-
- (NSUInteger) count
- (id) objectForKey: (id) key
- (NSArray*) allKeys
- (NSEnumerator*) keyEnumerator
- (NSArray*) allKeysForObject: (id) anObject
** 비교
-
- (BOOL) isEuqalToDictionary: (id) anObject
** 파일 입출력
-
- (NSString*) description
- (id) initWithContentsOfFile: (NSString*) path
편의생성자 : dictionaryWithContentsOfFile:
- (BOOL) writeToFile: (NSString*) path atomically: (BOOL) flag
* 9.5.3. NSMutableDictionary
** 사전 객체 초기화, 작성
-
- (id) initWithCapacity: (NSUInteger) capacity
편의생성자 : dictionaryWithCapacity:
** 엔트리 추가, 삭제
-
-(void) setObject: (id) anObject forKey: (id) aKey
키, 값 객체 모두 nil 은 안 된다.
- (void) addEntriesFromDictionary: (NSDictionary*) otherDic
- (void) setDictionary: (NSDictionary*) otherDic
지금까지 리시버에 저장되어 있던 에트리는 모두 삭제된다.
- (void) removeObjectForKey: (id) key
- (void) removeObjectsForKeys: (NSArray*) keyArray
- (void) removeAllObjects
9.6. 숫자값에 대응하는 랩터 클래스
-
Objective-C 에서는 정수나 실수 같은 자료형은 객체가 아니므로 그대로는 컬렉션에 저장할 수 없다.
-
숫자 값을 표현하는 클래스인 NSValue 와 그 서브 클래스인 NSNumber 가 있다.
이건 숫자값과 좌표 같은 자료형을 객체로 다루기 위한 랩퍼이다.
-
빈 객체를 뜻하는 NSNull 도 있다.
-
NSValue 와 NSNumber 는 클래스 클러스터로 제공되므로 NSValue 와 NSNumber 가 인스턴스의 직접 클래스가 아니라는 점, 일반적인 방법으로는 서브 클래스를 만들 수 없다는 점을 주의해야 한다.
* 9.6.1. NSNumber
** 초기화 작성
-
- (id) initWithInteger: (NSInteger) value
+ (NSNumber*) numberWithInteger: (NSInteger) value
** 값 참조
-
- (NSInteger) integerValue
** 기타
-
- (BOOL) isEqualToNumber: (NSNumber*) aNumber
- (NSComparisonResult) compare: (NSNumber*) aNumber
- (NSString*) stringValue
* 9.6.2. NSValue
-
아래의 클래스 메소드들이 있다.
valueWithPointer:
valueWithPoint:
valueWithRect:
valueWithSize:
valueWithRange:
-
(BOOL) isEqualToValue: (NSValue*) value
* 9.6.3. 형식 코드와 @encode()
-
NSValue 와 NSNumber 같은 클래스는 몇 가지 형을 유연하게 다루므로 내부에 있는 데이터가 실제로는 어떤 형인지 기록해두어야만 한다.
다른 프로세서나 스레드와 통신을 할 경우에도 보내는 데이터가 어떤 형인지를 알려줄 필요가 있다.
-
Objective-C 에서는 자료형을 표현하기 위해 C 문자열(const char*) 의 형 코드를 사용하지만 형에서 문자열을 쉽게 다룰 수 있도록 @encode() 라는 컴파일러 지시자가 있다.
@encode() 는 인수로 형식명을 받고 컴파일할 때는 대응하는 형의 코드를 바꿔서 사용한다.
예를 들어 @encode(int) 는 “i” 로, @encode(NSSize) 는 @{_NSSize=ff} 가 된다.
-
NSValue 에서는 형식 코드를 사용해 구조체 같은 자료형을 래핑한 인스턴스를 만들 수 있다.
그러려면 초기자 initWithBytes:objCType: 을 사용하고, 래핑된 값을 추출하려면 메서드 getValue: 를 사용한다.
- (id) initWithBytes: (const void*) value objCType: (const char*) type
인수 type 형의 코드를 사용해 인수 value 에 지정한 바이트 배열을 래핑한 인스턴스를 만든다.
호환 문제가 발생하지 않도록 인수 type 에는 C 문자열이 아닌 @encode() 를 반드시 지정하도록 한다.
편의생성자 : valueWithBytes:objType:
- (void) getValue: (void*) buffer
리시버가 가지고 있는 바이트 배열을 인수로 지정한 메모리 영역에 복사한다.
-
struct grid{
int x, y;
double weight;
};
struct grid foo, bar;
id obj = [[NSValue alloc] initWithBytes: &foo objType: @encode(struct grid)];
[obj getValue:&bar];
-
NSValue 는 크기가 정해진 데이터는 래핑할 수 있지만 변경 가능한 바이트 배열이나 요소 개수가 변하는 배열은 래핑할 수 없다.
구체적으로 말해 일반적인 C 문자열을 통째로 래핑할 수 없다.
-
NSValue 와 NSNumber 는 클래스 클러스터로 제공되므로 서브 클래스의 정의는 주의해야 한다.
* 9.6.4. NSNull
-
배열 객체와 사전 객체에는 요소로 nil 을 포함할 수 없다.
하지만 상황에 따라서는 유효한 값이 없다는 것을 뜻하는 어떤 표지가 필요할 때가 있다.
NSNull 은 이럴 때 사용할 수 있는 빈 객체를 나타내는 클래스이다.
-
+ (NSNull *) null
NSNull 인스턴스를 돌려주지만 반환된 객체는 항상 같은 상수 객체이다.
그래서 비교는 obj == [NSNull null] 과 같이 할 수 있다.
9.7. NSURL
* 9.7.1. 여기서 다루는 URL 이란
-
URL(Uniform Resource Locator)은 웹 브라우저에서 페이지를 참조할 때 사용하는 문자열로 알려져 있지만
로컬 머신 파일 위치를 나타내거나 HTTP 이외의 프로토콜로 참조되는 리소스를 표현할 때도 사용된다.
-
Mac OS X 및 iOS 는 NSURL 로 읽기가 가능한 리소스로, 다음의 네 가지 스킴만 다룬다.
http
https
ftp
file
-
URL 형식은 다음과 같다.
스킴명://호스트명/호스트 안에 있는 리소스를 나타내는 경로
-
http 일 때 로그인이 필요하다면 호스트명 부분에 사용자명과 암호, 포트 번호를 적을 수 있다.
경로 끝에는 페이지 속 위치를 나타내는 플래그먼트라고 불리는 문자열이 # 에 이어서 나오거나 각종 파라미터가 추가되기도 한다.
또한 경로에 알파벳이나 숫자 이외의 기호나 비 ASCII 문자가 포함될 때는 %를 써서 16진수로 표현하기도 한다.
-
스킴에 file 을 지정하면 호스트명을 지정한 파일의 위치를 나타낼 수 있지만 NSURL 에서는 호스트명에 localhost 를 지정하고 로컬 머신에 있는 파일명을 참조하는 방법도 사용할 수 있다.
로컬 머신에 유닉스의 파일 경로 표현으로 /Users/me/cool.jpg 라는 파일이 있다면 URL 은 다음과 같다.
file://localhost/Users/me/cool.jpg
-
경로에는 절대 경로와 상대 경로가 있다.
상대 경로로 리소스를 다타낼 때 기본이 되는 위치를 뜻하는 URL 을 베이스 URL 이라고 부른다.
* 9.7.2. NSURL 개요
-
NSURL 에서는 메서드에 따라 문자열을 자동으로 퍼센트 부호화하기도 한다.
그런 경우에는 NSString stringByAddingPercentEscapesUsingEncoding: 메소드를 호출한다.
문자 코드로 UTF-8 을 사용하므로 그 이외의 인코딩이 필요한 경우에는 이 메서드를 사용해서 미리 부호화해야 한다.
-
NSURL 관련 셀렉터 키워드와 매개변수명에는 string 과 path 두 가지 형태가 있으며, 이 둘 중 취사 선택을 해야 한다.
string 이라는 것은 URL 문자열을 표현한다.
반환값을 나타낼 때는 퍼센트 부호화된 URL 문자열 표현을 사용하며, 인수의 형태일 때도 퍼센트 부호화된 녀석이라 간주한다.
반대로 path 는 URL 경로 부분을 의미하여 반환값도 인수도 퍼센트 부호화하지 않은 문자열을 사용한다.
** 인스턴스 초기화 생성
-
- (id) initWithString: (NSString*) URLString
편의생성자 : URLWithString:
- (id) initWithString: (NSString*) URLString relativeToURL: (NSURL*) baseURL
절대 경로를 사용하고 싶을 때는 baseURL 에 nil
편의 생성자 : URLWithString:relativeToURL:
- (id) initFileURLWithPath: (NSString*) path
상대경로가 지정되었을 때는 프로세스의 현재 디렉터리가 베이스 URL 로 사용된다.
실행할 때 넘어온 경로가 디렉터리인지 어떤지 실제로 확인해서 디렉터리일 때는 끝에 / 를 추가한다.
경로가 디렉터리인지 명확하게 나타내기 위해서는 initFileURLWithPath:isDirectory: 초기자를 사용할 수 있다.
편의 생성자 : fileURLWithPath:
** URL 구성 요소
-
- (BOOL) isFileURL
- (NSURL*) baseURL
- (NSString*) absoluteString
- (NSURL*) absoluteURL
- (NSString*) relativePath
리시버가 절대 경로 URL 이면 경로 문자열 전체를 돌려준다.
- (NSString*) relativeString
** 경로 조작
-
- (NSString*) path
URL 경로 문자열( 호스트명 뒷부분 )을 return 한다.
경로 마지막 항목을 추출하려면 lastPathComponent, 확장자를 추출하려면 pathExtension 을 사용한다.
경로 구성 요소를 배열 객체로 추출하려면 pathComponents 를 사용한다.
- (NSURL*) URLByAppendingPathComponent: (NSString*) pathComponent
필요에 따라 “/“ 를 삽입한다.
- (NSURL*) URLByDeletingLastPathComponent
확장자를 삭제하려면 URLByDeletingPathExtension 을 사용한다.
** 파일 참조 URL
-
파일 시스템 중 파일 ID 로 파일을 참조하는 것이 있는데, 이것을 파일 참조 URL 이라고 부른다.
파일 참조 URL 은 파일명이 변하거나 다른 디렉터리로 이동해도 같은 파일을 계속 참조할 수 있는 특징이 있다.
-
- (NSURL*) fileReferenceURL
리시버가 파일 경로 URL 일 때는 파일 참조 URL 로 변환해서 새로운 인스턴스를 돌려준다.
반대로 파일 참조 URL 에서 파일 경로 URL 을 얻으려면 filePathURL 메서드를 사용한다.
- (BOOL) isFileReferenceURL
- (BOOL) checkResourceIsReachableAndReturnError: (NSError**) error
** 파일 속성의 참조와 설정
-
NSURL 을 사용해서 파일과 디렉터리, 볼륨(파일 시스템) 속성을 조사하거나 변경할 수 있다.
대표적인 예로 파일 크기, 수정 날짜, 권한 같은 속성값이 있는데, 이것은 NSFileManager 를 사용해서 조사할 수도 있지만 같은 기능은 아니다.
-
- (BOOL) getResourceValue: (id*)value forKey: (NSString*) key error: (NSError**) error
인수 key 로 지정한 속성값 객체를 value 에 가리키는 변수에 대입한다.
처리에 성공하면 YES 를 돌려준다.
여러 속성값을 한번에 설정하려면 메서드 resourceValuesForKeys:error: 를 사용한다.
- (BOOL) setResourceValue: (id)value forKey: (NSString*) key error: (NSError**) error
인수 value 값을 인수 key 로 지정한 속성의 새로운 값으로 설정한다.
처리에 성공하면 YES 이다.
여러 속성값을 한 번에 설정하려면 메서드 setResourceValues:error: 를 사용한다.
** 9.7.3. NSURL 을 사용한 리소스에 접근
-
- (id) initWithContentsOfFile: (NSString*) path
- (id) initWithContentsOfURL: (NSURL*) aURL
다음 글 : [Objective-C] 카테고리
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[Objective-C] 추상 클래스와 클래스 클러스터 (0) | 2018.01.03 |
---|---|
[Objective-C] 카테고리 (0) | 2018.01.02 |
[Objective-C] Foundation 프레임워크의 중요 클래스 - NSData, NSArray, NSSet (0) | 2017.12.31 |
[Objective-C] Foundation 프레임워크의 중요 클래스 - NSString, NSMutableString (0) | 2017.12.30 |
[Objective-C] NSObject 클래스와 런타임 시스템 (0) | 2017.12.29 |
댓글