Several common protocols in IOS: nscopying / nsmutablecopying

Time:2020-10-27

1. Some explanations

When it comes to nscopying and nsmutablecopying protocols, we have to say copy and mutablecopy.

If a class wants to support copy operation, it must implement the nscopying protocol, that is, the copywithzone method;

If a class wants to support mutablecopy operation, it must implement nsmutablecopying protocol, that is to say, implement mutablecopywithzone method;

Some classes in IOS system have implemented nscopying or nsmutablecopying protocol methods. If copy or mutablecopy messages are sent to system classes or user-defined classes that do not implement the corresponding methods, they will crash.

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[Person copyWithZone:]: unrecognized selector sent to instance 0x6080000314c0’

Sending copy and mutablecopy messages are both copy operations. However, the copying methods are slightly different for non container classes of immutable objects, non container classes of mutable objects, container classes of mutable objects, and container classes of immutable objects

Send copy message, the copied object is immutable;

Send mutablecopy message. The copied object is a variable object;

Therefore, the following operations will cause crash


NSMutableString *test1 = [[NSMutableString alloc]initWithString:@"11111"];
NSMutableString *test2 = [test1 copy];
[test2 appendString:@"22222"];

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[NSTaggedPointerString appendString:]: unrecognized selector sent to

2. System non container class

The non container classes provided by the system, such as nsstring and nsmutablestring, have the following features:

Send copy to immutable object to copy pointer; send mutalbecopy message to immutable object to copy content;


NSString *test3 = @"111111";
NSString *test4 = [test3 copy];
NSMutableString *test5 = [test3 mutableCopy];
NSLog(@"test3 is %p, test4 is %p, tast5 is %p",test3,test4,test5);
test3 is 0x10d6bb3a8, test4 is 0x10d6bb3a8, tast5 is 0x600000073e80

In other words, deep copy is used to send messages to the object;


NSMutableString *test11 = [[NSMutableString alloc]initWithString:@"444444"];
NSString *test12 = [test11 copy]; 
NSMutableString *test13 = [test11 mutableCopy]; 
NSLog(@"test11 is %p, test12 is %p, tast13 is %p",test11,test12,test13);
 
test11 is 0x600000073e00, test12 is 0xa003434343434346, tast13 is 0x600000073dc0

3. System container class

The container classes provided by the system, such as nsarray and nsdictionary, have the following features:

The immutable object copy is shallow copy, that is, pointer copy; sending mutablecopy is deep copy, that is, content copy;


NSArray *array = [NSArray arrayWithObjects:@"1", nil];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
NSLog(@"array is %p, copyArray is %p, mutableCopyArray is %p", array, copyArray, mutableCopyArray);
array is 0x60800001e580, copyArray is 0x60800001e580, mutableCopyArray is 0x608000046ea0

Variable object copy and mutablecopy are both single-layer deep copy, that is, single-layer content copy;


NSMutableArray *element = [NSMutableArray arrayWithObject:@1];
NSMutableArray *array = [NSMutableArray arrayWithObject:element];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
NSLog(@"array is %p, copyArray is %p, mutableCopyArray is %p", array, copyArray, mutableCopyArray);
[mutableCopyArray[0] addObject:@2];
NSLog(@"element is %@, array is %@, copyArray is %@, mutableCopyArray is %@", element,array,copyArray, mutableCopyArray);
 
2017-02-22 11:53:25.286 test[91520:3915695] array is 0x600000057670, copyArray is 0x600000000bc0, mutableCopyArray is 0x6080000582a0
2017-02-22 11:53:25.287 test[91520:3915695] element is (
1,
2
), array is (
 (
 1,
 2
)
), copyArray is (
 (
 1,
 2
)
), mutableCopyArray is (
 (
 1,
 2
)
)

4. Custom class

Important note:

1. So the code design is for business needs.

2. For custom classes, it is also true to decide whether copy and mutablecopy messages can be sent to objects;

1. The @ property declaration is decorated with copy

I have to say the difference between copy and strong when copying. I don’t talk about reference counting here.

Copy: copy an immutable copy and assign it to the attribute. Therefore, when the original object value changes, the property value will not change;

Strong: it may point to a variable object. If the variable object is modified externally, the attribute will be affected;

@interface Person : NSObject 
@property (nonatomic, copy) NSString *familyname;
@property (nonatomic, strong) NSString *nickname;
@end
Person *p1 = [[Person alloc]init];
 
Nsmutablestring * familyname = [[nsmutablestring alloc] initwithstring: @ "Zhang San"];
p1.familyname = familyname;
[familyname appendstring: @ "peak"];
 
NSLog(@"p1.familyname is %@",p1.familyname);
 
Nsmutablestring * nickname = [[nsmutablestring alloc] initwithstring: @ "two dogs"];
p1.nickname = nickname;
[nickname appendstring: @ "egg"];
 
NSLog(@"p1.nickname is %@", p1.nickname);
2017-02-22 13:53:58.979 test [98299:3978965] P1. Familyname is Zhang San
2017-02-22 13:53:58.979 test [98299:3978965] P1. Nickname is ergoudan

2. The copy of the object of the class

The only thing to note here is to pay attention to class inheritance.

This article has a very clear and detailed description. Here, I just copy the conclusion

Class 1 directly inherits from nsobject without calling [Super Cop] yWithZone:zone ]

2. The parent class implements the copy protocol, and the subclass implements the copy protocol. The subclass needs to call [Super Cop] yWithZone:zone ]

3. The parent class does not implement the copy protocol, while the subclass implements the copy protocol. The subclass does not need to call [Super Cop] yWithZone:zone ]

4. In copywithzone method, call [[[self class] alloc] init] to allocate memory

5、NSCopying

Nscopying is a protocol for copying objects.

If the object of class supports copying, the class should comply with and implement nscopying protocol.

There is only one method in the nscopying protocol, as follows:
- (id)copyWithZone:(NSZone *)zone { 
 Person *model = [[[self class] allocWithZone:zone] init];
 model.firstName = self.firstName;
 model.lastName = self.lastName;
 //Undisclosed members
 model->_nickName = _nickName;
 return model;
}

3、NSMutableCopying

When a custom class has a property that is a mutable object, mutablecopywithzone operation is performed when this attribute is copied.


- (id)copyWithZone:(NSZone *)zone {
 AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init];
 serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone];
 serializer.queryStringSerializationStyle = self.queryStringSerializationStyle;
 serializer.queryStringSerialization = self.queryStringSerialization;
 
 return serializer;
}

The above article discusses several common protocols in IOS, nscopying / nsmutablecopying, which is the whole content shared by Xiaobian. I hope it can give you a reference, and I hope you can support developeppaer more.

Recommended Today

Layout of angular material (2): layout container

Layout container Layout and container Using thelayoutDirective to specify the layout direction for its child elements: arrange horizontally(layout=”row”)Or vertically(layout=”column”)。 Note that if thelayoutInstruction has no value, thenrowIs the default layout direction. row: items arranged horizontally.max-height = 100%andmax-widthIs the width of the item in the container. column: items arranged vertically.max-width = 100%andmax-heightIs the height of the […]