애플 WWDC2013, Session 228에 소개된 내용들 중 iOS나 Mac 개발시 자주쓰일만한 팁들을 추려내서 간단히 정리해보았다.
서브스크립팅(subscripting) 사용하기
Modern Objective-C 문법이 적용되면서 NSDictionary나 NSArray같은 foundation 데이터 구조객체들은 서브스크립팅을 이용하여 다음과같이 간결하게 작성이 가능하게되었다.
[myArray objectAtIndex:3] -> myArray[3][myDictionary objectForKey:@"key"] -> myDictionary[@"key"]
사용자가 만든 커스텀 클래스에도 서브스크립팅을 위한 set/get메서드만 잘 정의해두면 훨씬 더 간결한 프로그램 작성이 가능하다.
MyCustomArray 클래스에
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
위 두가지 메서드 구현시 다음과같이 배열처럼 인덱스로 바로 접근 가능
get: NSLog(@“%@“, myCustomInstance[1]);
set: myCustomInstance[0] = @“test";
딕셔너리(dictionary)의 경우 아래 두가지 메서드를 구현해주면 된다.
- (id)objectAtKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
NSExpression: 문자열로된 수식 계산
스트링(string)형태로 된 수식을 계산하고 싶을때 유용하게 사용될 수 있다.
NSString *text = @"3 + 5 * 4e10";
NSExpression *e = [NSExpression expressionWithFormat:text, nil];
NSNumber *result = [e expressionValueWithObject:nil context:nil];
NSLog(@"result: %@", result);
위 코드의 출력값은 result: 200000000003 이다.
NSArray reverse ordering
reverseObjectEnumerator를 사용하면 손쉽게 reverse array를 만들 수 있다.
NSArray *numbers = @[ @1, @2, @3 ];
NSArray *reversed = numbers.reverseObjectEnumerator.allObjects;
NSNumber vs. NSValue
Objective-C를 접한지 얼마 안된경우 이 비슷한 이름을 가진 두가지 클래스의 차이점이 뭔지 헷갈릴경우가 많다.
구분하자면,
- NSNumber의경우 int, float, bool 등의 원시 타입(primitive type)을 객체화시켜 저장하는데 사용
- NSValue의 경우 scalar값들이나 struct (NSRange, CGPoint, NSRect 등)을 객체화시켜 저장
예1)
NSMutableArray *array = [@[] mutableCopy];
array[0] = [NSValue valueWithPoint:CGPointZero];
array[1] = [NSValue valueWithRange:NSMakeRange(3, 17)];
예2) 사용자정의 구조체
typedef struct RGB {
float red, green, blue;
} _RGB;
RGB color = {1.0f, 0.0f, 0.0f};
array[2] = [NSValue valueWithBytes:&color objCType:@encode(RGB)];
NSString이 아닌 객체를 dictionary의 key로 사용하기
딕셔너리에 키(key)에 대해 값(value)를 셋팅할경우, 키는 항상 copy되어 사용되기때문에 키로 사용되는 클래스는 항상 NSCopying 프로토콜을 따라야한다. 일반적으로 딕셔너리의 키값으로 많이 사용되는 NSString의 경우 이 프로토콜을 따르고있다.
myObject 객체가 NSCopying 프로토콜을 따를경우 에는 다음과 같이 사용해도 아무 문제가 없지만
mutableDic[myObject] = @42;
NSCopying 프로토콜을 따르지 않을경우 크래쉬가 발생한다. 이때 해당 객체가 NSCopying프로토콜을 따르도록 수정해도되지만, 해당객체가 다른 라이브러리에서와서 직접적인 수정이 어려운 경우 다음과같이 NSValue 객체로 한번 wrapping 해주면 문제가 해결된다(NSValue가 NSCopying프로토콜을 따르기 때문).
keyObject = [NSValue valueWithNonRetainedObject:myObject]
mutableDic[keyObject] = @42;
valueWithNonRetainedObject: 메서드의 경우 해당 객체(object)를 retain하지 않는다는 점에 주의해야 한다.
NSDataDetector
자주사용되는 특정 스트링 패턴을 긴 문자열내에서 손쉽게 추출해주는 라이브러리.
- Dates
- Addresses
- Links
- Phone numbers