Assignment and object copy in IOS objectivec

Time:2021-10-20

Assignment and object copy in IOS objectivec

In the development process, we often encounter the problem of object copy. Next, we discuss the assignment operation, object copy, and the differences and implementation methods between shallow copy and deep copy.

1、 Assignment operation of different objects

There are two types of objects in Objective-C, one is structure (or basic data type), and the other is nsobject object.

For a structure, the code will directly manipulate its entity, so the assignment operation will create a copy of the source object (a new object); For the nsobject object, the pointer must be used to operate the object, so its assignment operation is equivalent to copying the pointer rather than the object, that is, the assignment operation makes the source pointer and the new pointer point to the same nsobject object. It’s hard to understand this. Please see the following code:


// main.m 
 
#import <Foundation/Foundation.h> 
 
@interface TestObject : NSObject 
{ 
  @public 
  int x; 
  int y; 
} 
@end 
 
@implementation TestObject 
@end 
 
typedef struct TestStruct 
{ 
  int x; 
  int y; 
} 
TestStruct; 
 
int main(int argc, const char * argv[]) 
{ 
 
  @autoreleasepool { 
     
    TestStruct ts1 = {100, 50}; 
    NSLog(@"ts1: %p, %d, %d", &ts1, ts1.x, ts1.y); 
     
    TestStruct ts2 = ts1; 
    NSLog(@"ts2: %p, %d, %d", &ts2, ts2.x, ts2.y); 
 
    TestObject* to1 = [[[TestObject alloc] init] autorelease]; 
    NSLog(@"to1: %p, %d, %d", to1, to1->x, to1->y); 
     
    TestObject* to2 = to1; 
    NSLog(@"to2: %p, %d, %d", to2, to2->x, to2->y); 
     
  } 
  return 0; 
} 

The running results of the program are as follows:


ts1: 0x7fff63463898, 100, 50 
ts2: 0x7fff63463890, 100, 50 
to1: 0x7fc342d00370, 0, 0 
to2: 0x7fc342d00370, 0, 0 

The program code first defines a class testobject (inherited from nsobject), and then defines a structure teststruct. Both contain two integer member variables X and y. Then, in the main function, the program first allocates memory space for teststruct structure TS1 and assigns initial values to its member variables, X is 100 and Y is 50. Then print the address of the structure and the value of the member variable through the nslog function, that is, the first line of output. Then, the program executes an assignment statement to assign TS1 to another teststructure object TS2. This statement will allocate another block of memory for TS2, and then copy the value of each member variable of TS1. The second line of output also shows that the address is different, so if you modify the value of the member variable of TS1, it will not affect TS2.

Then let’s look at testobject. The program then allocates a new memory space using the alloc static method, then initializes through the init instance method (the value of all member variables is 0), and finally returns the first address of the memory space. The essence of to1 is a pointer to the created testobject object. Next, the program assigns to1 to to2. To2 is also a pointer to the testobject object. Its value is the same as to1, that is, both point to the same object. Therefore, in this case, the modification of to1 will affect to2 at the same time.

2、 Object copy

The nsobject class of the foundation framework provides two methods, copy and mutablecopy, which are used to copy nsobject objects. The copy method calls the copywithzone: method of the nsmutablecopying protocol, and mutablecopy calls the mutablecopywithzone: method of the nsmutablecopying protocol. Modify the above code as follows:

#import <Foundation/Foundation.h> 
 
@interface TestObject : NSObject 
{ 
  @public 
  int x; 
  int y; 
} 
@end 
 
@implementation TestObject 
- (NSString*)description 
{ 
  return [NSString stringWithFormat:@"%@: %p, x: %d, y: %d", [self class], self, x, y]; 
} 
@end 
 
typedef struct TestStruct 
{ 
  int x; 
  int y; 
} 
TestStruct; 
 
int main(int argc, const char * argv[]) 
{ 
  @autoreleasepool 
  {     
    TestObject* to1 = [[[TestObject alloc] init] autorelease]; 
    to1->x = 100; to1->y = 50; 
    TestObject* to2 = [[[TestObject alloc] init] autorelease]; 
    to2->x = 200; to2->y = 400; 
    TestObject* to3 = [[[TestObject alloc] init] autorelease]; 
    to3->x = 300; to3->y = 500; 
     
    //Create an array array1 containing to1, to2, to3 
    NSArray* array1 = [NSArray arrayWithObjects:to1, to2, to3, nil]; 
    NSLog(@"array1: %p, \n%@", array1, array1); 
     
    //Array2 is the result of array1 calling copy 
    NSArray* array2 = [array1 copy]; 
    NSLog(@"array2: %p, \n%@", array2, array2); 
    [array2 release]; 
     
    //Mutablearray2 is the result of array1 calling mutablecopy 
    NSMutableArray* mutableArray2 = [array1 mutableCopy]; 
    NSLog(@"mutableArray2: %@, %p, \n%@", [mutableArray2 class], mutableArray2, mutableArray2); 
    [mutableArray2 removeLastObject]; 
     
    NSLog(@"After remove last object of mutableArray2"); 
     
    NSLog(@"array1: %p, \n%@", array1, array1); 
    NSLog(@"array2: %p, \n%@", array2, array2); 
    NSLog(@"mutableArray2: %p, \n%@", mutableArray2, mutableArray2); 
     
    //Mutablearray3 is the result of mutablecopy called by mutablearray2 
    NSMutableArray* mutableArray3 = [mutableArray2 mutableCopy]; 
    NSLog(@"mutableArray3: %p, \n%@", mutableArray3, mutableArray3); 
    [mutableArray2 release]; 
     
    //Array4 is the result of mutablearray3 calling copy 
    NSArray* array4 = [mutableArray3 copy]; 
    NSLog(@"array4: %@, %p, \n%@", [array4 class], array4, array4); 
    [mutableArray3 release]; 
    [array4 release]; 
  } 
  return 0; 
}

The running results of the program are as follows:


2012-03-22 19:20:49.548 ObjectCopy[18042:403] array1: 0x7f9071414820,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400", 
  "TestObject: 0x7f9071414230, x: 300, y: 500" 
) 
2012-03-22 19:20:49.550 ObjectCopy[18042:403] array2: 0x7f9071414820,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400", 
  "TestObject: 0x7f9071414230, x: 300, y: 500" 
) 
2012-03-22 19:20:49.551 ObjectCopy[18042:403] mutableArray2: __NSArrayM, 0x7f9072800000,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400", 
  "TestObject: 0x7f9071414230, x: 300, y: 500" 
) 
2012-03-22 19:20:49.552 ObjectCopy[18042:403] After remove last object of mutableArray2 
2012-03-22 19:20:49.552 ObjectCopy[18042:403] array1: 0x7f9071414820,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400", 
  "TestObject: 0x7f9071414230, x: 300, y: 500" 
) 
2012-03-22 19:20:49.553 ObjectCopy[18042:403] array2: 0x7f9071414820,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400", 
  "TestObject: 0x7f9071414230, x: 300, y: 500" 
) 
2012-03-22 19:20:49.553 ObjectCopy[18042:403] mutableArray2: 0x7f9072800000,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400" 
) 
2012-03-22 19:20:49.557 ObjectCopy[18042:403] mutableArray3: 0x7f90729000d0,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400" 
) 
2012-03-22 19:20:49.558 ObjectCopy[18042:403] array4: __NSArrayI, 0x7f9071416e70,  
( 
  "TestObject: 0x7f90714141b0, x: 100, y: 50", 
  "TestObject: 0x7f90714141c0, x: 200, y: 400" 
) 

There are several points worth noting about the running results of the program. First, the addresses of array1 and array2 are the same, because the nsarray object cannot be modified after it is created. Secondly, the mutablecopy method of nsarray returns an nsmutablearray object. Third, for nsarray or nsmutablearray, mutablecopy method will create a new variable array object, but the value of each array member is only a pointer assignment of the original array, which is shallow copy. The opposite is deep copy, that is, when copying an array, instead of copying the reference of each element of the array, you create a new object that is the same as it.

Fourth, calling the mutablecopy method on the nsarray object returns an nsmutablearray object, while calling the copy method on the nsmutablearray object returns an nsarray object instead of an nsmutablearray object.

Of course, the nsarray and nsmutablearray classes in the foundation framework discussed above. If you want to copy the objects of the class you created, you need to let the class implement the nscopying protocol.

If you have any questions, please leave a message or go to the community of this site for exchange and discussion. Thank you for reading. I hope it can help you. Thank you for your support to this site!

Recommended Today

SQL exercise 20 – Modeling & Reporting

This blog is used to review and sort out the common topic modeling architecture, analysis oriented architecture and integration topic reports in data warehouse. I have uploaded these reports to GitHub. If you are interested, you can have a lookAddress:https://github.com/nino-laiqiu/TiTanI recorded a relatively complete development process in my hexo blog deployed on GitHub. You can […]