您好,登錄后才能下訂單哦!
1、幾點說明
說到NSCopying和NSMutableCopying協議,不得不說的就是copy和mutableCopy。
如果類想要支持copy操作,則必須實現NSCopying協議,也就是說實現copyWithZone方法;
如果類想要支持mutableCopy操作,則必須實現NSMutableCopying協議,也就是說實現mutableCopyWithZone方法;
iOS系統中的一些類已經實現了NSCopying或者NSMutableCopying協議的方法,如果向未實現相應方法的系統類或者自定義類發送copy或者mutableCopy消息,則會crash。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person copyWithZone:]: unrecognized selector sent to instance 0x6080000314c0'
發送copy和mutableCopy消息,均是進行拷貝操作,但是對不可變對象的非容器類、可變對象的非容器類、可變對象的容器類、不可變對象的容器類中復制的方式略有不同;但如下兩點是相同的:
發送copy消息,拷貝出來的是不可變對象;
發送mutableCopy消息,拷貝出來的是可變對象;
故如下的操作會導致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、系統非容器類
系統提供的非容器類中,如NSString,NSMutableString,有如下特性:
向不可變對象發送copy,進行的是指針拷貝;向不可變對象發送mutalbeCopy消息,進行的是內容拷貝;
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
向可變對象發送copy和mutableCopy消息,均是深拷貝,也就是說內容拷貝;
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、系統容器類
系統提供的容器類中,如NSArray,NSDictionary,有如下特性:
不可變對象copy,是淺拷貝,也就是說指針復制;發送mutableCopy,是深復制,也就是說內容復制;
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
可變對象copy和mutableCopy均是單層深拷貝,也就是說單層的內容拷貝;
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、自定義的類
重要說明:
1、所以的代碼設計均是針對業務需求。
2、對于自定義的類,決定能否向對象發送copy和mutableCopy消息也是如此;
1、@property 聲明中用 copy 修飾
不得不說下copy和strong在復制時候的區別,此處不講引用計數的問題。
copy:拷貝一份不可變副本賦值給屬性;所以當原對象值變化時,屬性值不會變化;
strong:有可能指向一個可變對象,如果這個可變對象在外部被修改了,那么會影響該屬性;
@interface Person : NSObject @property (nonatomic, copy) NSString *familyname; @property (nonatomic, strong) NSString *nickname; @end Person *p1 = [[Person alloc]init]; NSMutableString *familyname = [[NSMutableString alloc]initWithString:@"張三"]; p1.familyname = familyname; [familyname appendString:@"峰"]; NSLog(@"p1.familyname is %@",p1.familyname); NSMutableString *nickname = [[NSMutableString alloc]initWithString:@"二狗"]; p1.nickname = nickname; [nickname appendString:@"蛋兒"]; NSLog(@"p1.nickname is %@", p1.nickname); 2017-02-22 13:53:58.979 test[98299:3978965] p1.familyname is 張三 2017-02-22 13:53:58.979 test[98299:3978965] p1.nickname is 二狗蛋兒
2、類的對象的copy
此處唯一需要說明的一點就是注意類的繼承。
這篇文章有非常清晰詳細的說明,此處只照搬下結論:
1 類直接繼承自NSObject,無需調用[super copyWithZone:zone]
2 父類實現了copy協議,子類也實現了copy協議,子類需要調用[super copyWithZone:zone]
3 父類沒有實現copy協議,子類實現了copy協議,子類無需調用[super copyWithZone:zone]
4、copyWithZone方法中要調用[[[self class] alloc] init]來分配內存
5、NSCopying
NSCopying是對象拷貝的協議。
類的對象如果支持拷貝,該類應遵守并實現NSCopying協議。
NSCopying協議中的方法只有一個,如下: - (id)copyWithZone:(NSZone *)zone { Person *model = [[[self class] allocWithZone:zone] init]; model.firstName = self.firstName; model.lastName = self.lastName; //未公開的成員 model->_nickName = _nickName; return model; }
3、NSMutableCopying
當自定義的類有一個屬性是可變對象時,對此屬性復制時要執行mutableCopyWithZone操作。
- (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; }
以上這篇淺談iOS中幾個常用協議 NSCopying/NSMutableCopying就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。