iOS의 얕은 복사와 깊은 복사 분석 (copy 및 mutable Copy)

6922 단어
ios는 copy와mutablecopy 방법을 제공했다. 말 그대로 copy는imutable의 대상을 복제한 것이고mutablecopy는mutable의 대상을 복제한 것이다.
copy와 retain의 차이점:
copy는 새 대상을 만듭니다.retain은 포인터를 만듭니다. 인용 대상의 계수는 1입니다.Copy 속성은 두 대상의 내용이 같고 새 대상retain은 1이며 기존 대상의 인용 계수와 상관없이 기존 대상은 변하지 않습니다.copy는 상하문에 대한 대상의 의존을 감소합니다.
retain 속성은 두 대상의 주소가 같다는 것을 나타낸다. (포인터를 만들고 포인터를 복사한다.) 내용은 당연히 같다. 이 대상의retain 값 +1 즉,retain은 포인터 복사이고,copy는 내용 복사이다.
물론 iOS에서 모든 대상이 copy,mutable Copy를 지원하는 것은 아니다. NSCopying 프로토콜을 준수하는 클래스는 copy 메시지를 보낼 수 있고, NSMutable Copying 프로토콜을 준수하는 클래스는 mutable Copy 메시지를 보낼 수 있다.만약 상소 두 프로토콜을 준수하지 않고 코피나mutable Copy를 보냈다면 이상이 발생할 것입니다.그러나 기본적인ios류는 이 두 프로토콜을 준수하지 않았다.copy를 사용자 정의하려면 NSCopying을 준수하고 copyWithZone을 실현해야 합니다: 방법,mutableCopy를 사용자 정의하려면 NSMutableCopying을 준수하고,mutableCopyWithZone을 실현해야 합니다. 방법.
우선 우리는 이런 전제가 필요하다.
  [array addObject:obj];
이렇게 하면obj의 인용계수는 1이 증가하고,remove를 사용하면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의 인용과 마찬가지로 모두 2입니다.한편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 대상이기 때문에 위에서 말한 것은 틀릴 수 있습니다.시스템의 비용기류 대상에 대해 우리는 변할 수 없는 대상을 복제하면 코피는 바늘 복제(얕은 복사)와mutable Copy는 대상 복제(깊은 복사)라고 볼 수 있다.가변 대상을 복제하면 모두 깊이 복사하지만, 코피가 되돌아오는 대상은 가변적이지 않습니다.
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];

array1과 arrayCopy1은 포인터 복제이고 mArrayCopy1은 대상 복제이며 mArrayCopy1은 기간 내의 요소를 삭제하거나 추가할 수 있습니다.그러나 컨테이너 내의 요소 컨텐트는 포인터로 복사됩니다.
다음은 또 다른 예로 테스트해 보겠습니다.

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 object AtIndex:1]와 [deepCopy Array object AtIndex:0]는 같은 메모리를 가리키지만 수정할 수 없습니다. 변경할 수 없기 때문입니다.그래서 바늘 복제는 충분합니다.
그래서 이것은 완전한 의미의 깊은 복사가 아니지만 apple의 공식 문서는 이를 deep copy로 열거하고 copy와mutablity의 관계 설명을 추가했기 때문에 여기에 설명을 한다(이쪽은 좀 의심스럽고 이해가 가는 가르침이 있다).
아니면 우리 스스로 깊은 복사를 실현하는 방법(약).
3. 객체 사용자 정의
만약 우리가 정의한 대상이라면, 우리 스스로 NSCopying을 실현해야 한다. NSMutable Copying. 이렇게 하면 copy와mutable copy를 호출할 수 있다.예를 들면 다음과 같습니다.

@interface MyObj : NSObject
{
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와mutable Copy)에 대해 이렇게 많이 소개해 드리니 도움이 되었으면 좋겠습니다!

좋은 웹페이지 즐겨찾기