iOS 의 얕 은 복사 와 깊 은 복사(copy 와 mutableCopy)

ios 는 copy 와 mutablecopy 방법 을 제공 합 니 다.말 그대로 copy 는 imutable 대상 을 복사 한 것 이 고 mutablecopy 는 mutable 대상 을 복사 한 것 입 니 다.
copy 와 retain 의 차이 점:
copy 는 새 대상 을 만 드 는 것 입 니 다.retain 은 지침 을 만 드 는 것 입 니 다.참조 대상 수 에 1 을 추가 합 니 다.Copy 속성 은 두 대상 의 내용 이 같 고 새로운 대상 retain 은 1 로 기 존 대상 의 인용 계수 와 상 관 없 이 기 존 대상 은 변화 가 없다 는 것 을 나타 낸다.copy 는 대상 이 문맥 에 대한 의존 을 감소 합 니 다.
retain 속성 은 두 대상 의 주소 가 같다 는 것 을 나타 낸다.(하나의 지침 을 만 들 고 포인터 복사)내용 은 당연히 같다.이 대상 의 retain 값+1 은 retain 은 포인터 복사 이 고 copy 는 내용 복사 이다.
물론 iOS 에서 모든 대상 이 copy,mutableCopy 를 지원 하 는 것 은 아 닙 니 다.NSCopying 프로 토 콜 을 준수 하 는 클래스 는 copy 메 시 지 를 보 낼 수 있 고 NSMutableCopying 프로 토 콜 을 준수 하 는 클래스 는 mutableCopy 메 시 지 를 보 낼 수 있 습 니 다.항소 두 협 의 를 지 키 지 않 고 copy 나 mutableCopy 를 보 냈 다 면 이상 이 발생 할 수 있 습 니 다.그러나 기본 ios 클래스 는 이 두 가지 협 의 를 지 키 지 않 았 다.copy 를 사용자 정의 하려 면 NSCopying 을 준수 하고 copy WithZone:방법 을 실현 해 야 합 니 다.mutableCopy 를 사용자 정의 하려 면 NSMutableCopying 을 준수 하고 mutableCopyWithZone:방법 을 실현 해 야 합 니 다.
우선 우 리 는 이런 전제 가 필요 하 다.
  [array addObject:obj];
이렇게 하면 obj 의 인용 수 는 1 이 증가 하고 reove 를 사용 하면 obj 의 인용 수 는 1 이 줄어든다.
ios 집합 메모리 처리 가 이 렇 습 니 다.
그러면 obj 가 array 에 만 있다 고 가정 합 니 다.
  id temp = [array objectAtIndex:0];
  [array removeObjectAtIndex:0];
temp 을 다시 사용 하려 면 오류 가 발생 합 니 다.이때 obj 가 풀 려 났 기 때 문 입 니 다.
(NSString 으로 테스트 를 한다 면@"abc"가 상수 임 을 주의 하 세 요:-)
프로그램 에서 집합 류 의 전 가 를 자주 만 날 수 있 기 때문에 간단 한 retain 이 반드시 충분 하지 않 기 때문에 집합 내용 에 대한 복사,즉 깊 은 복사 가 필요 하 다.
다음은 우리 가 토론 해 보 겠 습 니 다.
Ios 는 copy 와 mutablecopy 방법 을 제공 합 니 다.말 그대로 copy 는 imutable 대상 을 복사 한 것 이 고 mutablecopy 는 mutable 대상 을 복사 한 것 입 니 다.
다음은 몇 가지 예 를 들 어 설명 할 것 이다.
1.시스템 의 비 용기 클래스 대상
NSString,NSNumber 등의 대상 을 말 합 니 다.

  NSString *string = @"origion";
  NSString *stringCopy = [string copy];
  NSMutableString *stringMCopy = [string mutableCopy];
  [stringMCopy appendString:@"!!"];
메모 리 를 보면 string 과 stringCopy 가 가리 키 는 것 은 같은 메모리 영역(apple 약 참조 weak reference 라 고도 함)입 니 다.이때 stringCopy 의 인용 수 는 string 과 같 습 니 다.그리고 stringMCopy 는 우리 가 말 한 진정한 의미 의 복사 입 니 다.시스템 은 새 메모 리 를 분 배 했 지만 포인터 가 가리 키 는 문자열 은 string 이 가리 키 는 것 과 같 습 니 다.
다음 의 예 를 보십시오.

NSMutableString *string = [NSMutableString stringWithString: @"origion"];
NSString *stringCopy = [string copy];
NSMutableString *mStringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy];
[mStringCopy appendString:@"mm"];//error
[string appendString:@" origion!"];
[stringMCopy appendString:@"!!"];
위의 네 개의 NSString 대상 이 할당 한 메모 리 는 모두 다르다.그러나 mStringCopy 에 대해 서 는 사실 imutable 대상 이기 때문에 위 에서 잘못 보고 할 수 있 습 니 다.
시스템 의 비 용기 류 대상 에 대해 우 리 는 가 변 적 이지 않 은 대상 을 복사 하면 copy 는 포인터 복사(얕 은 복사)와 mutableCopy 는 대상 복사(깊 은 복사)라 고 볼 수 있다.가 변 대상 에 대한 복사 라면 모두 깊 은 복사 이지 만 복사 가 되 돌아 오 는 대상 은 가 변 적 이지 않다.
2.시스템 의 용기 클래스 대상
NSArray,NSDictionary 등 을 말 합 니 다.용기 류 자체 에 대해 서도 위 에서 논의 한 결론 이 적용 되 며 복제 후 용기 내 대상 의 변 화 를 논의 해 야 한다.

//copy       ,mutablecopy      
NSArray *array1 = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];
NSArray *arrayCopy1 = [array1 copy];
//arrayCopy1  array   NSArray  (       ),  array              
NSLog(@"array1 retain count: %d",[array1 retainCount]);
NSLog(@"array1 retain count: %d",[arrayCopy1 retainCount]);
NSMutableArray *mArrayCopy1 = [array1 mutableCopy];
//mArrayCopy1 array1     ,      array1  ,        array1             。mArrayCopy1          
[mArrayCopy1 addObject:@"de"];
[mArrayCopy1 removeObjectAtIndex:0];
array 1 과 array Copy 1 은 포인터 복사 이 고,mArray Copy 1 은 대상 복사 이 며,mArray Copy 1 은 기간 내 요 소 를 변경 할 수 있 습 니 다:삭제 하거나 추가 할 수 있 습 니 다.그러나 주의해 야 할 것 은 용기 안의 요소 내용 은 모두 지침 복사 이다.
다음은 다른 예 로 테스트 해 보 겠 습 니 다.

NSArray *mArray1 = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *mArrayCopy2 = [mArray1 copy];
NSLog(@"mArray1 retain count: %d",[mArray1 retainCount]);
NSMutableArray *mArrayMCopy1 = [mArray1 mutableCopy];
NSLog(@"mArray1 retain count: %d",[mArray1 retainCount]);
//mArrayCopy2,mArrayMCopy1 mArray1           ,              ――     
//     
NSMutableString *testString = [mArray1 objectAtIndex:0];
//testString = @"1a1";//     testString   ,    @“1a1”       testString
[testString appendString:@" tail"];//                 
이 를 통 해 알 수 있 듯 이 용기 의 요소 대상 은 항상 포인터 복사 이다.원소 대상 도 대상 복제 가 필요 하 다 면 깊 은 복사 가 필요 하 다.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Articles/Copying.html
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"first"],[NSStringstringWithString:@"b"],@"c",nil];
NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: array]];
trueDeepCopyArray 는 완전한 의미 의 깊 은 복사 이 고,deepCopyArray 는 그렇지 않 습 니 다.deepCopyArray 의 불가 변 요소 에 대해 서 는 포인터 복사 입 니 다.아니면 우리 스스로 깊 은 복 사 를 하 는 방법.용기 의 어떤 요소 가 변 하지 않 는 다 면 복사 가 끝 난 후에 도 대상 은 변 할 수 없 기 때문에 포인터 만 복사 하면 된다.용기 안의 요 소 를 다시 할당 하지 않 으 면 포인터 복사 만으로 도 충분 합 니 다.
예 를 들 어[[array objectAtIndex:0]appendstring:@"sd"]이후 다른 용기 안의 대상 은 영향 을 받 지 않 습 니 다.
[[array objectAtIndex:1]과[deepCopyArray objectAtIndex:0]같은 메모 리 를 가리 키 지만 우 리 는 그것 을 수정 할 방법 이 없다.왜냐하면 그것 은 바 꿀 수 없 기 때문이다.그래서 포인터 복사 만으로 도 충분 합 니 다.
그래서 이것 은 완전한 의미 의 깊 은 복사 가 아니 지만 애플 의 공식 문 서 는 deep copy 로 분류 되 었 고 copy 와 mutablity 의 관계 설명 을 추가 하 였 으 므 로 여기 서 설명 하 겠 습 니 다.
아니면 우리 스스로 깊 은 복 사 를 실현 하 는 방법(약).
3.사용자 정의 대상
우리 가 정의 하 는 대상 이 라면 NSCopying,NSMutableCopying 을 실현 해 야 합 니 다.그러면 copy 와 mutablecopy 를 호출 할 수 있 습 니 다.예 를 들 어:

@interface MyObj : NSObject<NSCopying,NSMutableCopying>
{
NSMutableString *name;
NSString *imutableStr;
int age;
}
@property (nonatomic, retain) NSMutableString *name;
@property (nonatomic, retain) NSString *imutableStr;
@property (nonatomic) int age;
@end
@implementation MyObj
@synthesize name;
@synthesize age;
@synthesize imutableStr;
- (id)init
{
if (self = [super init])
{
self.name = [[NSMutableString alloc]init];
self.imutableStr = [[NSString alloc]init];
age = -1;
}
return self;
}
- (void)dealloc
{
[name release];
[imutableStr release];
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone
{
MyObj *copy = [[[self class] allocWithZone:zone] init];
copy->name = [name copy];
copy->imutableStr = [imutableStr copy];
// copy->name = [name copyWithZone:zone];;
// copy->imutableStr = [name copyWithZone:zone];//
copy->age = age;
return copy;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
MyObj *copy = NSCopyObject(self, 0, zone);
copy->name = [self.name mutableCopy];
copy->age = age;
return copy;
}
iOS 의 얕 은 복사 와 깊 은 복사(copy 와 mutableCopy)에 대해 이렇게 많이 소개 해 드 리 니 도움 이 되 셨 으 면 좋 겠 습 니 다!

좋은 웹페이지 즐겨찾기