NSString은 왜 copy 키워드를 사용합니까? strong을 사용하면 무슨 문제가 있습니까? OC의 깊은 복사와 얕은 복사입니다.

4924 단어
먼저 딥 카피와 얕은 카피, 딥 카피는 메모리 카피, 얕은 카피는 지침 카피입니다.
코드를 쓸 때 두 가지copy 방법이 있어요.
- (id)copy;
- (id)mutableCopy;

copy에서 나온 객체는 불변 유형이고mutableCopy에서 나온 객체는 소프트 유형입니다.
NSString
    NSString *sourceString = [NSString stringWithFormat:@"youyouyou"];
    
    // 
    NSString *copyStr = [sourceString copy];
    
    // 
    NSMutableString *mutableStr = [sourceString mutableCopy];
    
    NSLog(@"sourceString : %@     %p",sourceString,sourceString);
    NSLog(@"copyStr : %@     %p",copyStr,copyStr);
    NSLog(@"mutableStr : %@     %p",mutableStr,mutableStr);

실행 결과
2017-06-30 09:59:42.695 ttt[780:22226] sourceString : youyouyou     0xa250d09434250d09
2017-06-30 09:59:42.696 ttt[780:22226] copyStr : youyouyou     0xa250d09434250d09
2017-06-30 09:59:42.696 ttt[780:22226] mutableStr : youyouyou     0x608000261f00
NSString 대상에게 copy는 새로운 메모리 주소를 생성하지 않을 것임을 알 수 있다. mutable Copy는 새로운 메모리 주소를 생성하고 새로운 메모리 주소를 생성하는 것은 깊은 복사이고 그렇지 않으면 얕은 복사이다.
NSMutableString
    NSMutableString *sourceString = [NSMutableString stringWithFormat:@"youyouyou"];
    
    // 
    NSString *copyStr = [sourceString copy];
    
    // 
    NSMutableString *mutableStr = [sourceString mutableCopy];
    
    NSLog(@"sourceString : %@     %p",sourceString,sourceString);
    NSLog(@"copyStr : %@     %p",copyStr,copyStr);
    NSLog(@"mutableStr : %@     %p",mutableStr,mutableStr);
실행 결과
2017-06-30 10:04:48.601 ttt[799:24932] sourceString : youyouyou     0x60000007e280
2017-06-30 10:04:48.601 ttt[799:24932] copyStr : youyouyou     0xa250d09434250d09
2017-06-30 10:04:48.601 ttt[799:24932] mutableStr : youyouyou     0x60000007e2c0

NSMuatbleString copy 및 mutable Copy 에 새로 생성된 메모리는 모두 딥 카피입니다.
그리고 속성으로 말할 때 코피를 사용하든strong을 사용하든지.
Person 클래스 테스트 작성
#import 

@interface Person : NSObject

@property (nonatomic, copy) NSString *copyStr;
@property (nonatomic, strong) NSString *strongStr;

NSString 테스트 코드
    Person *person = [[Person alloc]init];
    
    NSString *sourceString = [NSString stringWithFormat:@"youyouyou"];
    
    person.scopyString = sourceString;
    person.strongString = sourceString;
    
    sourceString = @"aaa";

    NSLog(@"sourceString : %@     %p",sourceString,sourceString);
    NSLog(@"person.scopyString : %@     %p",person.scopyString,person.scopyString);
    NSLog(@"person.strongStr : %@     %p",person.strongString,person.strongString);

실행 결과
2017-06-30 10:29:50.926 ttt[920:36840] sourceString : aaa     0x10f53f0f8
2017-06-30 10:29:50.926 ttt[920:36840] person.scopyString : youyouyou     0xa250d09434250d09
2017-06-30 10:29:50.927 ttt[920:36840] person.strongStr : youyouyou     0xa250d09434250d09

이렇게 보면strong은copy의 효과와 같이 원본 문자열을 바꾼 후에도 영향을 주지 않는다. 이것은 원본 문자열이person에게 변할 수 없기 때문이다.scopy String 및 person.strongString 후 그들 셋이 함께 @ "you you"의 메모리 주소를 가리키면 원본 문자열이 @ "aaa"원본 문자열로 바뀌고 @ "aaa"의 메모리 주소를 가리키는person입니다.scopy String 및 person.strongString은 @ "you you"의 메모리 주소를 가리키기 때문에 변경되지 않습니다
NSMutableString 테스트 코드
    Person *person = [[Person alloc]init];
    
    NSMutableString *sourceString = [NSMutableString stringWithFormat:@"youyouyou"];
    
    person.scopyString = sourceString;
    person.strongString = sourceString;
    
    [sourceString appendString:@"aaa"];

    NSLog(@"sourceString : %@     %p",sourceString,sourceString);
    NSLog(@"person.scopyString : %@     %p",person.scopyString,person.scopyString);
    NSLog(@"person.strongStr : %@     %p",person.strongString,person.strongString);

실행 결과
2017-06-30 10:44:16.771 ttt[946:42747] sourceString : youyouyouaaa     0x6080002738c0
2017-06-30 10:44:16.772 ttt[946:42747] person.scopyString : youyouyou     0xa250d09434250d09
2017-06-30 10:44:16.772 ttt[946:42747] person.strongStr : youyouyouaaa     0x6080002738c0

이번에는 값을 부여하고 원본 문자열을 변경하는 copy 수식의 변하지 않고 strong 수식의 변화를 볼 수 있습니다. NSMutable String에 대한 copy 실행 방법은 새로운 메모리 copy 수식의 속성을 깊이 복사하는 것입니다. 메모리 주소가 바뀌었고 strong은 계수 +1 메모리 주소인지 원본 문자열인지 인용하기 때문에 copy 수식의 속성에 영향을 주지 않습니다.
copy와strong 수식의 set 방법은 다음과 같습니다
//copy 
- (void)setScopyString:(NSString *)scopyString {
    _scopyString = [scopyString copy];
}

//strong 
- (void)setStrongString:(NSString *)strongString {
    _strongString = strongString;
}

이렇게 하면 원본 문자열이 가변 형식일 때 코피를 실행하는 방법이 깊은 복사라는 것을 알 수 있다
그래서 정리를 해볼게요.
원본 문자열이 변경되지 않을 때copy strong이 원본 문자열을 변경하는 것과 같습니다
원본 문자열이 가변 형식일 때copy수식은 원본 문자열을 깊이 복사하여 변경하는 것입니다. 원본 문자열은copy의 속성 내용에 영향을 주지 않습니다strong수식의 속성은 원본 문자열의 변화에 따라 변경됩니다

좋은 웹페이지 즐겨찾기