淺談iOS中幾個(gè)常用協(xié)議 NSCopying/NSMutableCopying
1、幾點(diǎn)說(shuō)明
說(shuō)到NSCopying和NSMutableCopying協(xié)議,不得不說(shuō)的就是copy和mutableCopy。
如果類想要支持copy操作,則必須實(shí)現(xiàn)NSCopying協(xié)議,也就是說(shuō)實(shí)現(xiàn)copyWithZone方法;
如果類想要支持mutableCopy操作,則必須實(shí)現(xiàn)NSMutableCopying協(xié)議,也就是說(shuō)實(shí)現(xiàn)mutableCopyWithZone方法;
iOS系統(tǒng)中的一些類已經(jīng)實(shí)現(xiàn)了NSCopying或者NSMutableCopying協(xié)議的方法,如果向未實(shí)現(xiàn)相應(yīng)方法的系統(tǒng)類或者自定義類發(fā)送copy或者mutableCopy消息,則會(huì)crash。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person copyWithZone:]: unrecognized selector sent to instance 0x6080000314c0'
發(fā)送copy和mutableCopy消息,均是進(jìn)行拷貝操作,但是對(duì)不可變對(duì)象的非容器類、可變對(duì)象的非容器類、可變對(duì)象的容器類、不可變對(duì)象的容器類中復(fù)制的方式略有不同;但如下兩點(diǎn)是相同的:
發(fā)送copy消息,拷貝出來(lái)的是不可變對(duì)象;
發(fā)送mutableCopy消息,拷貝出來(lái)的是可變對(duì)象;
故如下的操作會(huì)導(dǎo)致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、系統(tǒng)非容器類
系統(tǒng)提供的非容器類中,如NSString,NSMutableString,有如下特性:
向不可變對(duì)象發(fā)送copy,進(jìn)行的是指針拷貝;向不可變對(duì)象發(fā)送mutalbeCopy消息,進(jìn)行的是內(nèi)容拷貝;
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
向可變對(duì)象發(fā)送copy和mutableCopy消息,均是深拷貝,也就是說(shuō)內(nèi)容拷貝;
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、系統(tǒng)容器類
系統(tǒng)提供的容器類中,如NSArray,NSDictionary,有如下特性:
不可變對(duì)象copy,是淺拷貝,也就是說(shuō)指針復(fù)制;發(fā)送mutableCopy,是深復(fù)制,也就是說(shuō)內(nèi)容復(fù)制;
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
可變對(duì)象copy和mutableCopy均是單層深拷貝,也就是說(shuō)單層的內(nèi)容拷貝;
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、自定義的類
重要說(shuō)明:
1、所以的代碼設(shè)計(jì)均是針對(duì)業(yè)務(wù)需求。
2、對(duì)于自定義的類,決定能否向?qū)ο蟀l(fā)送copy和mutableCopy消息也是如此;
1、@property 聲明中用 copy 修飾
不得不說(shuō)下copy和strong在復(fù)制時(shí)候的區(qū)別,此處不講引用計(jì)數(shù)的問(wèn)題。
copy:拷貝一份不可變副本賦值給屬性;所以當(dāng)原對(duì)象值變化時(shí),屬性值不會(huì)變化;
strong:有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性;
@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、類的對(duì)象的copy
此處唯一需要說(shuō)明的一點(diǎn)就是注意類的繼承。
這篇文章有非常清晰詳細(xì)的說(shuō)明,此處只照搬下結(jié)論:
1 類直接繼承自NSObject,無(wú)需調(diào)用[super copyWithZone:zone]
2 父類實(shí)現(xiàn)了copy協(xié)議,子類也實(shí)現(xiàn)了copy協(xié)議,子類需要調(diào)用[super copyWithZone:zone]
3 父類沒(méi)有實(shí)現(xiàn)copy協(xié)議,子類實(shí)現(xiàn)了copy協(xié)議,子類無(wú)需調(diào)用[super copyWithZone:zone]
4、copyWithZone方法中要調(diào)用[[[self class] alloc] init]來(lái)分配內(nèi)存
5、NSCopying
NSCopying是對(duì)象拷貝的協(xié)議。
類的對(duì)象如果支持拷貝,該類應(yīng)遵守并實(shí)現(xiàn)NSCopying協(xié)議。
NSCopying協(xié)議中的方法只有一個(gè),如下:
- (id)copyWithZone:(NSZone *)zone {
Person *model = [[[self class] allocWithZone:zone] init];
model.firstName = self.firstName;
model.lastName = self.lastName;
//未公開(kāi)的成員
model->_nickName = _nickName;
return model;
}
3、NSMutableCopying
當(dāng)自定義的類有一個(gè)屬性是可變對(duì)象時(shí),對(duì)此屬性復(fù)制時(shí)要執(zhí)行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中幾個(gè)常用協(xié)議 NSCopying/NSMutableCopying就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
iOS應(yīng)用開(kāi)發(fā)中的文字選中操作控件UITextView用法講解
這篇文章主要介紹了iOS應(yīng)用開(kāi)發(fā)中的文字選中操作控件UITextView用法講解,代碼基于傳統(tǒng)的Objective-C語(yǔ)言,需要的朋友可以參考下2016-02-02
IOS 開(kāi)發(fā)之Object-C中的對(duì)象詳解
這篇文章主要介紹了IOS 開(kāi)發(fā)之Object-C中的對(duì)象詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
iOS開(kāi)發(fā)之路--仿網(wǎng)易抽屜效果
本文是IOS開(kāi)發(fā)之路系列的第一篇,主要講訴了如何仿網(wǎng)易新聞客戶端實(shí)現(xiàn)抽屜效果,全部源代碼都分享給大家,希望對(duì)大家有所幫助2014-08-08
iOS開(kāi)發(fā)中UITableview控件的基本使用及性能優(yōu)化方法
這篇文章主要介紹了iOS開(kāi)發(fā)中UITableview控件的基本使用及性能優(yōu)化方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-12-12
iOS微信瀏覽器回退不刷新實(shí)例(監(jiān)聽(tīng)瀏覽器回退事件)
下面小編就為大家?guī)?lái)一篇iOS微信瀏覽器回退不刷新實(shí)例(監(jiān)聽(tīng)瀏覽器回退事件)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
iOS TabBarItem設(shè)置紅點(diǎn)(未讀消息)
本文主要介紹了iOS利用TabBarItem設(shè)置紅點(diǎn)(未讀消息)的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-04-04

