IOS - 심층 및 얕은 복제 이해

4186 단어 iOS기본 개념
OC 그룹의 깊이 복사와 얕은 복사
얕은 복사: 바늘 복사, 원본 대상과 새 대상은 같은 주소를 가리킨다. 즉, 얕은 복사는 새로운 파일로 복귀하지만 두 파일의 주소는 여전히 하나이다.얕은 복사는 변할 수 없는 그룹(예를 들어 NSArray, NSSet, NS사전)만 코피를 만나야 얕은 복사이고 나머지는 모두 깊은 복사이다.
Dog * dog1 = [Dog new];
//  , 
Dog * dog2 = dog1;

딥 카피, 직접 정의한 클래스는 일반적으로 NSCopying, NSMutable Copying 프로토콜을 따라야 한다
Dog.h

@interface Dog : NSObject
@property (nonatomic) NSInteger age;
@end
Dog.m

@implementation Dog
- (id)copyWithZone:(NSZone *)zone
{
    Dog * dog = [[self class] allocWithZone:zone];
    dog.age = self.age;
    return dog;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    Dog * dog = [[self class] allocWithZone:zone];
    dog.age = self.age;
    return dog;
}

- (NSString *) description {
    return [NSString stringWithFormat:@"dog age: %ld", self.age];
}

@end
main.m

Dog * dog1 = [Dog new];
dog1.age = 5;

NSLog(@"dog1: %p, %@", dog1, dog1);

// mutableCopy  , 
Dog * dog2 = [dog1 mutableCopy];
dog2.age = 10;

// copy  
//  , ,  copy   mutableCopy  , 
Dog * dog2 = [dog1 copy];
dog2.age = 10;

NSLog(@"dog2: %p, %@", dog2, dog2);

OC 가변수 그룹의 깊이 복사와 얕은 복사
"수조에는 대상의 주소만 저장된 것이지 대상의 본체를 저장한 것이 아니다."
따라서 수조를 깊이 복사한 후에 대상의 주소가 다시 만들어졌습니다.
NSMutableArray * arr1 = [NSMutableArray new];

for (int i = 0; i < 3; i++) {
    Dog * dog = [Dog new];
    [arr1 addObject:dog];
}

NSLog(@"arr1: %p, %@", arr1, arr1);
NSMutableArray * arr2 = [arr1 mutableCopy];
NSLog(@"arr2: %p, %@", arr2, arr2);
 :
2017-010-10 10:55:39.895  [901:303] arr1: 0x1001089c0, (
    "",
    "",
    ""
)
2017-10-10 10:55:39.917  [901:303] arr2: 0x100301ad0, (
    "",
    "",
    ""
)

"수조에는 대상의 주소만 저장된 것이지 대상의 본체를 저장한 것이 아니기 때문이다."따라서 Dog 객체의 공간은 복제되지 않습니다.
따라서 가변수 그룹의'심도 복사'는 그 중의 모든 요소를 복제하지 않았고 그 중의 대상 요소는 얕은 복제만 했다!
해결 방법: 모든 객체를 복제합니다.
NSMutableArray * arr2 = [NSMutableArray new];
for (int i = 0; i < arr1.count; i++) {
    Dog * newDog = [arr1[i] copy];
    [arr2 addObject:newDog];
}

NSLog(@"arr2: %p, %@", arr2, arr2);

OC에서 수조에 대한 깊은 복사는 당연히 그 중의 원소 공간을 모두 복사했다고 생각할 수 없다.실제로 그 중의 원소는 단지 얕은 복사일 뿐이다!
깊은 복사가 필요하다면 원소 하나하나를 통해 깊은 복사를 해서 가변수 그룹에 다시 추가할 수 있습니다!
COPY는 불변 객체의 복사본을 반환하고 MutalbeCopy는 불변 객체의 복사본을 반환합니다.
NSArray *array=[NSArray arrayWithObjects:@"one",@"two", nil];
NSMutableArray *array1=[array copy];
[array1 addObject:@"three"];  //error
NSMutableArray *array2=[array mutableCopy];
[array2 addObject:@"three"];  //right
// insert code here...
NSLog(@"Hello, World!");

비교와 구별
복제 대상의 기본 개념: 하나의 대상을 복제하여 복제본 대상을 저장하는 새로운 메모리를 개척한다.
만약 대상이 복제 기능을 갖추고 싶다면 반드시 협의와 협의를 실현해야 한다
NSObject 자체가 가지고 있는 상용 대상은 NSNumber, NSString, NSArray, NSDictionary, NSMutableArray, NSMutableDictionay, NSMutableString이다. copy가 생성한 대상은 변할 수 없고mutableCopy가 생성한 대상은 변할 수 있다.
COPY와 Mutable Copy의 차이점
COPY는 불변 객체의 복사본을 반환하고 MutalbeCopy는 불변 객체의 복사본을 반환합니다.
얕은copy와 진한copy
얕은 복제는 대상 자체를 복제하고 대상의 속성, 포함된 대상은 복제하지 않는다.
얕은 복사는 포인터만 복사할 뿐 새로운 메모리 공간을 만들지 않습니다.
객체의 속성 및 기타 객체를 포함하여 전체 복사하기
Foundation 프레임워크는 복제를 지원하는 클래스입니다. 기본값은 얕은 복제입니다.
객체의 사용자 지정 복제본
대상은 복제 기능이 있어 NSCopying, NSMutable Copying 프로토콜, 이 프로토콜을 실현하는 copy WithZone 방법과 mutable Copy WithZone 방법을 실현해야 한다.
딥 카피와 얕은 카피의 차이는 copyWithZone 방법의 실현에 있다.
copy,mutableCopy,retain 사이의 관계
Foundation 대상에서 copy가 변할 수 없는 대상일 때retain
mutableCopy를 사용할 때 원본 대상이 변할 수 있든 없든 간에 복사본은 변할 수 있고 진정한 의미의copy를 실현한다
복사 대상을 사용할 때 복사 대상은 변할 수 없습니다.
NSFoundation, 우리가 copy를 할 때 변할 수 없는 대상이 될 때, 기본 copy는 모두 얕은 복사입니다. 이것은retain에 해당합니다
mutableCopy를 사용할 때 대상이 변할 수 있든 없든 깊은 복사를 할 수 있습니다
retain은 두 대상이 같은 바늘을 가리키는 것과 같다
요약: copy 및 mutableCopy:
copy: 가변 대상은 깊이 복사이고 가변 대상은 얕은 복사입니다.객체의 가변 여부를 복사된 객체와 일치시킬지 여부를 반환합니다.
mutableCopy: 항상 딥 카피입니다.항상 가변 객체가 반환됩니다.

좋은 웹페이지 즐겨찾기