코딩하는 나귀

보통 NSArray에서 mutableCopy 함수를 사용해 복사를 하게 되면 원본과 똑같은 값을 지닌 NSMutableArray 객체를 생성해준다.
하지만 NSDictionary에서 mutableCopy 함수를 사용해 복사를 하게 되는 경우 똑같이
복사를 하기는 하지만 값으로 배열이 있는 경우 그 주소만을 복사할 뿐 내용을 복사해 새로운 객체를 만들어 주지않는 다는 것이다. 즉, 배열은 그대로 두고 배열의 주소를 가르키는 변수만을 하나 더 만들어 거기에 같은 주소를 적어 놓았을 뿐이라는 말이다.
그래서 NSDictionary의 복사를 위해서는 함수를 별도 제작해야 한다.

함수 내용을 간단히 설명하면 복사하는 Dictionary의 각 키에 해당하는 값이 NSDictionary인지 NSArray인지 아니면 그 외의 값인지를 판단하여 하위 복사를 하는 것이다. 같은 예로 윈도우에서 폴더 밑에 폴더가 있니 있으면 재귀호출을 하는 머 그런 것과 비슷하다. (사실 따지자면 재귀호출과는 좀 다르지만 돌아가는 모양새는 똑같다.)

소스는 '시작하세요! 아이폰3 프로그래밍' 책에서 발취한 내용이다.
사용은 복사를 해야하는 소스쪽에서 헤더파일을 Include하고 사용하면 된다.

[헤더파일]
//NSDictionary-MutableDeepCopy.h

#import <Foundation/Foundation.h>

@interface NSDictionary(MutableDeepCopy)
- (NSMutableDictionary *)mutableDeepCopy;
@end


[구현파일]
//NSDictionary-MutableDeepCopy.m

#import "NSDictionary-MutableDeepCopy.h"

@implementation NSDictionary(MutableDeepCopy)
- (NSMutableDictionary *)mutableDeepCopy {
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for( id key in keys) {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        if([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if(oneCopy == nil)
            oneCopy = [oneValue copy];
   
        [ret setValue:oneCopy forKey:key];
    }
    return ret;
}
@end

아래 내용은 틀린 내용이여서 찍찍~!!  Copy관련 함수는 참조 카운터 유지한 상태로 반환 되는 것이 맞습니다. 

- 내가 알기로는 함수에서 객체를 만들어 리턴할 때는 autorelease 해서 돌려줘야 하는 걸로 배웠는데 이 함수에서는 할당만 하고 만다. 그래서 난 밑에 처럼 쓰고 있다.
내가 잘못알고 있는건 아닌지... -_-;;
NSMutableDictionary *ret = [[[NSMutableDictionary alloc] initWithCapacity:[self count]] autorelease];