[OC Foundation 프레임워크 - 17] copy 구문

19539 단어 copy
하나의 대상이 copy 또는mutableCopy 방법으로 대상의 복사본을 만들 수 있습니다
1.copy
NSCopying 프로토콜 필요
만들어진 건요.
NSString, NSArray, NSDictionary와 같은 변경되지 않는 복제본
 
(1) 불변 객체 호출 copy(NSSring 제외)
새로운 대상이 생기지 않고 대상 자체를 되돌려줍니다.retain, 계수기 +1
얕은 복사에 속한다
 
 1         NSArray *arr1 = [NSArray arrayWithObjects:@" ", @" ", nil];

 2         NSLog(@"arr1.addr: %p", arr1); // 0x1002052b0

 3         NSLog(@"arr1.retainCount: %ld", arr1.retainCount); // 1

 4 

 5        

 6         NSArray *arr2 = [arr1 copy];

 7         NSLog(@"arr1.addr: %p", arr1); // 0x1002052b0

 8         NSLog(@"arr1.retainCount: %ld", arr1.retainCount); // 2  <--  , retain, retainCount+1

 9         NSLog(@"arr2.addr: %p", arr2); //0x1002052b0 <--  , 

10         NSLog(@"arr2.retainCount: %ld", arr2.retainCount); // 2 <--  , retainCount

 
(2) 가변 객체 호출copy(NSMutableString은 하나의 NSString 상수 객체를 복사함)
변할 수 없는 대상을 되돌려주지만, 원래의 대상이 아니라, 깊은 복사에 속한다
 1         NSMutableArray *arr1 = [NSMutableArray array];

 2         [arr1 addObject:@"123"];

 3         [arr1 addObject:@"abc"];

 4         NSLog(@"arr1.addr: %p", arr1); // 0x100204840

 5         NSLog(@"arr1.retainCount: %ld", arr1.retainCount); // 1

 6        

 7        

 8         NSMutableArray *arr2 = [arr1 copy];

 9         NSLog(@"arr1.addr: %p", arr1); // 0x100204840

10         NSLog(@"arr1.retainCount: %ld", arr1.retainCount); // 1 <--  , retainCount 

11         NSLog(@"arr2.addr: %p", arr2); // 0x100300000 <--  , , NSArray

12         NSLog(@"arr2.retainCount: %ld", arr2.retainCount); // 1 <--  , retainCount 

 
(3) 중점: NSString의 특수성
@\"\"을(를) 사용하여 초기화했기 때문에 데이터는 상수 풀에 저장됩니다.
 
NSString이 문자열의 상수를 가리키기 때문에 시스템은 회수하지 않고 인용 계수를 만들지 않습니다. 설령 우리가 NSString 변수에 대해retain이나release를 어떻게 사용하든지 간에,retainCount는 -1입니다. (기호 최대치 없음)
 1         NSString *str1 = [[NSString alloc] initWithString:@"abc"];

 2         NSLog(@"str1.addr: %p", str1); // 0x100001030

 3         NSLog(@"str1.retainCount: %ld", str1.retainCount); // -1 <--  , 

 4        

 5         NSString *str2 = [str1 copy];

 6         NSLog(@"str1.addr: %p", str1); // 0x100001030

 7         NSLog(@"str1.retainCount: %ld", str1.retainCount); // -1 <--  copy, retain, release retianCount

 8         NSLog(@"str2.addr: %p", str2); // 0x100001030 <--  

 9         NSLog(@"str2.retainCount: %ld", str2.retainCount); // -1 <--  retainCount

10        

11         [str1 retain];

12         NSLog(@"after retain -> str1.retainCount: %ld", str1.retainCount); // -1 <--  copy, retain, release retianCount

13         [str2 release];

14         NSLog(@"after release -> str2.retainCount: %ld", str2.retainCount); // -1 <--  copy, retain, release retianCount

 
NSString 변수에 retainCount를 적용하려면:
다른 "NSString"을 가리키면
대상
문자열 상수
1         //  NSString , 

2         NSString *str1 = [NSString stringWithFormat:@"abc"];

3         NSLog(@"%ld", str1.retainCount); // -1

4         NSString *str2 = [NSString stringWithString:str1];

5         NSLog(@"%ld", str2.retainCount); // 1

 
(4) copy에서 나온 것은 변할 수 없는 대상이다. 예를 들어 NSMutableString에서 copy를 호출하여 만든 것은 실제적으로 NSString이다.
 1         //   NSMutableString *mstr1 = @"abc",   mstr1 = @"abc";  

 2         NSMutableString *mstr1 = [[NSMutableString alloc] initWithString:@"abc"];

 3         NSLog(@"mstr1.addr: %p", mstr1); // 0x100404990

 4         NSLog(@"mstr1.retainCount: %ld", mstr1.retainCount); // 1

 5 

 6 

 7         NSMutableString *mstr2 = [mstr1 copy];

 8         NSLog(@"mstr1.addr: %p", mstr1); // 0x100404990

 9         NSLog(@"mstr1.retainCount: %ld", mstr1.retainCount); // 1 <--  , retainCount 

10         NSLog(@"mstr2.addr: %p", mstr2); // 0x63626135 <--  , , 

11         NSLog(@"mstr2.retainCount: %ld", mstr2.retainCount); // -1 <--  

 
2.mutableCopy
NSMutable Copying 프로토콜 필요
NSMutable String, NSMutable Array, NSMutable Dictionary와 같은 가변 복사본을 만듭니다.
 
(1) 불변 객체 호출mutableCopy
새 객체 생성, 새 객체와 구 객체의 카운터가 독립적이고 상호 간섭이 없으며 딥 카피에 속함
1         NSString *str1 = [[NSString alloc] initWithString:@"abc"];

2         NSLog(@"str1.addr: %p", str1); // 0x100001030

3         NSLog(@"str1.retainCount: %ld", str1.retainCount); // -1 <--  , 

4 

5         NSMutableString *mstr2 = [str1 mutableCopy]; // mutableCopy   NSMutableString  

6         NSLog(@"str1.addr: %p", str1); // 0x100001030

7         NSLog(@"str1.retainCount: %ld", str1.retainCount); // -1 <--  ,  copy, retain, release retianCount

8         NSLog(@"mstr2.addr: %p", mstr2); // 0x100106460 <--  , 

9         NSLog(@"mstr2.retainCount: %ld", mstr2.retainCount); // 1 <--  NSMutableString ,retainCount == 1

 
(2) 소프트 객체 호출mutableCopy
새 객체 생성, 새 객체와 구 객체의 카운터가 독립적이고 상호 간섭이 없으며 딥 카피에 속함
1         NSMutableString *mstr1 = [[NSMutableString alloc] initWithString:@"abc"];

2         NSLog(@"mstr1.addr: %p", mstr1); // 0x100402910

3         NSLog(@"mstr1.retainCount: %ld", mstr1.retainCount); // 1

4 

5         NSMutableString *mstr2 = [mstr1 mutableCopy]; // mutableCopy   NSMutableString  

6         NSLog(@"mstr1.addr: %p", mstr1); // 0x100402910

7         NSLog(@"mstr1.retainCount: %ld", mstr1.retainCount); // 1

8         NSLog(@"mstr2.addr: %p", mstr2); // 0x100300e90 <--  , 

9         NSLog(@"mstr2.retainCount: %ld", mstr2.retainCount); // 1

 
3. 사용자 정의 클래스의 copy
1 @interface Student : NSObject

2 

3 //copy setter release ,copy 

4 @property (nonatomic, copy) NSString *name;

5 

6 @end

 
외부 NSMutable String 대상을 student의 setter에 전송합니다. 외부 대상이 바뀔 때, student에서copy가 오는 대상은 바뀌지 않습니다.
retain이나 assign을 사용하면 같은 대상을 가리키기 때문에 영향을 줍니다
==>NSMutableString으로 전송할 때(구성원 변수는 NSString) 일반적으로 copy 정책을 사용하고 기타는retain을 사용합니다.
 
(1) 구현
(2) 구현 - (id) copyWithZone: (NSZone *) zone
1 - (id)copyWithZone: (NSZone *) zone

2 {

3      Student *stu = [[Student allocWithZone:zone] init];

4      stu.name = self.name;

5      return stu;

6 }

 

좋은 웹페이지 즐겨찾기